1

Merge branch 'refactoring' into error-handling

# Conflicts:
#	src/main/java/mops/gruppen2/controller/Gruppen2Controller.java
#	src/main/java/mops/gruppen2/domain/Exceptions/UserAlreadyExistsException.java
#	src/main/java/mops/gruppen2/domain/Exceptions/UserNotFoundException.java
#	src/main/java/mops/gruppen2/domain/Group.java
#	src/main/java/mops/gruppen2/domain/event/AddUserEvent.java
#	src/main/java/mops/gruppen2/domain/event/CreateGroupEvent.java
#	src/main/java/mops/gruppen2/domain/event/DeleteUserEvent.java
#	src/main/java/mops/gruppen2/domain/event/Event.java
#	src/main/java/mops/gruppen2/domain/event/UpdateGroupDescriptionEvent.java
#	src/main/java/mops/gruppen2/domain/event/UpdateGroupTitleEvent.java
#	src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java
#	src/main/java/mops/gruppen2/domain/exception/EventException.java
#	src/main/java/mops/gruppen2/domain/exception/GroupIdMismatchException.java
#	src/main/java/mops/gruppen2/domain/exception/GroupNotFoundException.java
#	src/main/java/mops/gruppen2/domain/exception/NoValueException.java
#	src/main/java/mops/gruppen2/service/ControllerService.java
#	src/main/java/mops/gruppen2/service/GroupService.java
#	src/main/java/mops/gruppen2/service/UserService.java
#	src/main/resources/templates/errorRenameLater.html
This commit is contained in:
Christoph
2020-03-18 23:40:39 +01:00
57 changed files with 741 additions and 631 deletions

View File

@ -40,13 +40,15 @@
<property name="eachLine" value="true"/> <property name="eachLine" value="true"/>
</module> </module>
<module name="LineLength"> <!-- <module name="LineLength">-->
<property name="fileExtensions" value="java"/> <!-- <property name="fileExtensions" value="java"/>-->
<property name="max" value="100"/> <!-- <property name="max" value="100"/>-->
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/> <!-- <property name="ignorePattern"-->
</module> <!-- value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>-->
<!-- </module>-->
<module name="TreeWalker"> <module name="TreeWalker">
<module name="SuppressWarningsHolder"/>
<module name="OuterTypeFilename"/> <module name="OuterTypeFilename"/>
<module name="IllegalTokenText"> <module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/> <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
@ -284,14 +286,14 @@
<property name="allowedAnnotations" value="Override, Test"/> <property name="allowedAnnotations" value="Override, Test"/>
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/> <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/>
</module> </module>
<module name="MissingJavadocMethod"> <!-- <module name="MissingJavadocMethod">-->
<property name="scope" value="public"/> <!-- <property name="scope" value="public"/>-->
<property name="minLineCount" value="2"/> <!-- <property name="minLineCount" value="2"/>-->
<property name="allowedAnnotations" value="Override, Test"/> <!-- <property name="allowedAnnotations" value="Override, Test"/>-->
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/> <!-- <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/>-->
</module> <!-- </module>-->
<module name="MethodName"> <module name="MethodName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/> <property name="format" value="^[a-z][a-zA-Z0-9][a-zA-Z0-9_]*$"/>
<message key="name.invalidPattern" <message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/> value="Method name ''{0}'' must match pattern ''{1}''."/>
</module> </module>

View File

@ -1,15 +1,10 @@
package mops.gruppen2.config; package mops.gruppen2.config;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Group;
import mops.gruppen2.service.EventService; import mops.gruppen2.service.EventService;
import mops.gruppen2.service.GroupService; import mops.gruppen2.service.GroupService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration @Configuration
public class Gruppen2Config { public class Gruppen2Config {

View File

@ -3,17 +3,19 @@ package mops.gruppen2.controller;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.apiWrapper.UpdatedGroupRequestMapper; import mops.gruppen2.domain.api.GroupRequestWrapper;
import mops.gruppen2.domain.event.Event; import mops.gruppen2.domain.event.Event;
import mops.gruppen2.service.*; import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.service.APIFormatterService;
import mops.gruppen2.service.EventService;
import mops.gruppen2.service.GroupService;
import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.InputStream;
import java.util.List; import java.util.List;
/** /**
@ -23,40 +25,37 @@ import java.util.List;
@RequestMapping("/gruppen2/api") @RequestMapping("/gruppen2/api")
public class APIController { public class APIController {
private final SerializationService serializationService;
private final EventService eventService; private final EventService eventService;
private final GroupService groupService; private final GroupService groupService;
public APIController(SerializationService serializationService, EventService eventService, GroupService groupService) { public APIController(EventService eventService, GroupService groupService) {
this.serializationService = serializationService;
this.eventService = eventService; this.eventService = eventService;
this.groupService = groupService; this.groupService = groupService;
} }
@GetMapping("/updateGroups/{status}") @GetMapping("/updateGroups/{status}")
@Secured("ROLE_api_user") @Secured("ROLE_api_user")
@ApiOperation(value = "Gibt alle Gruppen zurück in denen sich etwas geändert hat") @ApiOperation("Gibt alle Gruppen zurück in denen sich etwas geändert hat")
public UpdatedGroupRequestMapper updateGroup(@ApiParam("Letzter Status des Anfragestellers") @PathVariable Long status) throws EventException { public GroupRequestWrapper updateGroup(@ApiParam("Letzter Status des Anfragestellers") @PathVariable Long status) throws EventException {
List<Event> events = eventService.getNewEvents(status); List<Event> events = eventService.getNewEvents(status);
UpdatedGroupRequestMapper updatedGroupRequestMapper = APIFormatterService.wrapp(eventService.getMaxEvent_id(), groupService.projectEventList(events));
return updatedGroupRequestMapper; return APIFormatterService.wrap(eventService.getMaxEvent_id(), groupService.projectEventList(events));
} }
@GetMapping("/getGroupIdsOfUser/{teilnehmer}") @GetMapping("/getGroupIdsOfUser/{teilnehmer}")
@Secured("ROLE_api_user") @Secured("ROLE_api_user")
@ApiOperation(value = "Gibt alle Gruppen zurück in denen sich ein Teilnehmer befindet") @ApiOperation("Gibt alle Gruppen zurück in denen sich ein Teilnehmer befindet")
public List<Long> getGroupsOfUser(@ApiParam("Teilnehmer dessen groupIds zurückgegeben werden sollen") @PathVariable String teilnehmer) throws EventException { public List<Long> getGroupsOfUser(@ApiParam("Teilnehmer dessen groupIds zurückgegeben werden sollen") @PathVariable String teilnehmer) {
return eventService.getGroupsOfUser(teilnehmer); return eventService.getGroupsOfUser(teilnehmer);
} }
@GetMapping("/getGroup/{groupId}") @GetMapping("/getGroup/{groupId}")
@Secured("ROLE_api_user") @Secured("ROLE_api_user")
@ApiOperation(value = "Gibt die Gruppe mit der als Parameter mitgegebenden groupId zurück") @ApiOperation("Gibt die Gruppe mit der als Parameter mitgegebenden groupId zurück")
public Group getGroupFromId(@ApiParam("GruppenId der gefordeten Gruppe") @PathVariable Long groupId) throws EventException { public Group getGroupFromId(@ApiParam("GruppenId der gefordeten Gruppe") @PathVariable Long groupId) throws EventException {
List<Event> eventList = eventService.getEventsOfGroup(groupId); List<Event> eventList = eventService.getEventsOfGroup(groupId);
List<Group> groups = groupService.projectEventList(eventList); List<Group> groups = groupService.projectEventList(eventList);
return groups.get(0); return groups.get(0);
} }

View File

@ -6,13 +6,23 @@ import mops.gruppen2.domain.Exceptions.GroupNotFoundException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role; import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User; import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.security.Account; import mops.gruppen2.security.Account;
import mops.gruppen2.service.*; import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.CsvService;
import mops.gruppen2.service.GroupService;
import mops.gruppen2.service.InviteLinkRepositoryService;
import mops.gruppen2.service.KeyCloakService;
import mops.gruppen2.service.UserService;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.annotation.SessionScope; import org.springframework.web.context.annotation.SessionScope;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;
@ -27,14 +37,13 @@ import java.util.List;
@RequestMapping("/gruppen2") @RequestMapping("/gruppen2")
public class Gruppen2Controller { public class Gruppen2Controller {
@Autowired
Gruppen2Config gruppen2Config;
private final KeyCloakService keyCloakService; private final KeyCloakService keyCloakService;
private final GroupService groupService; private final GroupService groupService;
private final UserService userService; private final UserService userService;
private final ControllerService controllerService; private final ControllerService controllerService;
private final InviteLinkRepositoryService inviteLinkRepositoryService; private final InviteLinkRepositoryService inviteLinkRepositoryService;
@Autowired
Gruppen2Config gruppen2Config;
public Gruppen2Controller(KeyCloakService keyCloakService, GroupService groupService, UserService userService, ControllerService controllerService, InviteLinkRepositoryService inviteLinkRepositoryService) { public Gruppen2Controller(KeyCloakService keyCloakService, GroupService groupService, UserService userService, ControllerService controllerService, InviteLinkRepositoryService inviteLinkRepositoryService) {
this.keyCloakService = keyCloakService; this.keyCloakService = keyCloakService;
@ -72,19 +81,34 @@ public class Gruppen2Controller {
@RolesAllowed({"ROLE_orga", "ROLE_actuator)"}) @RolesAllowed({"ROLE_orga", "ROLE_actuator)"})
@PostMapping("/createLecture") @PostMapping("/createLecture")
public String pCreateLecture(KeycloakAuthenticationToken token, public String pCreateLecture(KeycloakAuthenticationToken token,
@RequestParam(value = "title") String title, @RequestParam("title") String title,
@RequestParam(value = "beschreibung") String beschreibung, @RequestParam("beschreibung") String beschreibung,
@RequestParam(value = "visibility", required = false) Boolean visibility, @RequestParam(value = "visibility", required = false) Boolean visibility,
@RequestParam(value = "file") MultipartFile file) throws IOException, EventException { @RequestParam(value = "file", required = false) MultipartFile file) throws IOException, EventException {
Account account = keyCloakService.createAccountFromPrincipal(token); Account account = keyCloakService.createAccountFromPrincipal(token);
List<User> userList = CsvService.read(file.getInputStream()); List<User> userList = new ArrayList<>();
if (!file.isEmpty()) {
userList = CsvService.read(file.getInputStream());
}
visibility = visibility == null; visibility = visibility == null;
controllerService.createLecture(account, title, beschreibung, visibility, userList); controllerService.createLecture(account, title, beschreibung, visibility, userList);
return "redirect:/gruppen2/"; return "redirect:/gruppen2/";
} }
@RolesAllowed({"ROLE_orga", "ROLE_actuator)"})
@PostMapping("/details/members/addUsersFromCsv")
public String addUsersFromCsv(@RequestParam("group_id") Long groupId,
@RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
List<User> userList = new ArrayList<>();
if (!file.isEmpty()) {
userList = CsvService.read(file.getInputStream());
}
controllerService.addUserList(userList, groupId);
return "redirect:/gruppen2/details/members/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
@GetMapping("/createGroup") @GetMapping("/createGroup")
public String createGroup(KeycloakAuthenticationToken token, Model model) { public String createGroup(KeycloakAuthenticationToken token, Model model) {
@ -94,11 +118,11 @@ public class Gruppen2Controller {
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/findGroup") @GetMapping("/findGroup")
public String findGroup(KeycloakAuthenticationToken token, Model model, @RequestParam(value = "suchbegriff", required = false) String suchbegriff) throws EventException { public String findGroup(KeycloakAuthenticationToken token, Model model, @RequestParam(value = "suchbegriff", required = false) String search) throws EventException {
Account account = keyCloakService.createAccountFromPrincipal(token); Account account = keyCloakService.createAccountFromPrincipal(token);
List<Group> groupse = new ArrayList<>(); List<Group> groupse = new ArrayList<>();
if (suchbegriff != null) { if (search != null) {
groupse = groupService.findGroupWith(suchbegriff,account); groupse = groupService.findGroupWith(search, account);
} }
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token)); model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
model.addAttribute("gruppen", groupse); model.addAttribute("gruppen", groupse);
@ -108,8 +132,8 @@ public class Gruppen2Controller {
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/createGroup") @PostMapping("/createGroup")
public String pCreateGroup(KeycloakAuthenticationToken token, public String pCreateGroup(KeycloakAuthenticationToken token,
@RequestParam(value = "title") String title, @RequestParam("title") String title,
@RequestParam(value = "beschreibung") String beschreibung, @RequestParam("beschreibung") String beschreibung,
@RequestParam(value = "visibility", required = false) Boolean visibility) throws EventException { @RequestParam(value = "visibility", required = false) Boolean visibility) throws EventException {
Account account = keyCloakService.createAccountFromPrincipal(token); Account account = keyCloakService.createAccountFromPrincipal(token);
@ -121,10 +145,10 @@ public class Gruppen2Controller {
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
@GetMapping("/details/{id}") @GetMapping("/details/{id}")
public String showGroupDetails(KeycloakAuthenticationToken token, Model model, @PathVariable (value="id") Long id) throws EventException, ResponseStatusException { public String showGroupDetails(KeycloakAuthenticationToken token, Model model, @PathVariable("id") Long groupId) throws EventException, ResponseStatusException {
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token)); model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
Group group = userService.getGroupById(id); Group group = userService.getGroupById(groupId);
Account account = keyCloakService.createAccountFromPrincipal(token); Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail()); User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
if (group != null) { if (group != null) {
@ -140,21 +164,23 @@ public class Gruppen2Controller {
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/detailsBeitreten") @PostMapping("/detailsBeitreten")
public String joinGroup(KeycloakAuthenticationToken token, Model model, @RequestParam(value = "id") Long id) throws EventException { public String joinGroup(KeycloakAuthenticationToken token, Model model, @RequestParam("id") Long groupId) throws EventException {
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token)); model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
Account account = keyCloakService.createAccountFromPrincipal(token); Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail()); User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
Group group = userService.getGroupById(id); Group group = userService.getGroupById(groupId);
if(group.getMembers().contains(user)) return "errorRenameLater"; //hier soll eigentlich auf die bereits beigetretene Gruppe weitergeleitet werden if (group.getMembers().contains(user)) {
controllerService.addUser(account,id); return "errorRenameLater"; //hier soll eigentlich auf die bereits beigetretene Gruppe weitergeleitet werden
}
controllerService.addUser(account, groupId);
return "redirect:/gruppen2/"; return "redirect:/gruppen2/";
} }
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/detailsSearch") @GetMapping("/detailsSearch")
public String showGroupDetailsNoMember(KeycloakAuthenticationToken token, Model model, @RequestParam(value = "id") Long id) throws EventException { public String showGroupDetailsNoMember(KeycloakAuthenticationToken token, Model model, @RequestParam("id") Long groupId) throws EventException {
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token)); model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
Group group = userService.getGroupById(id); Group group = userService.getGroupById(groupId);
if (group != null) { if (group != null) {
model.addAttribute("group", group); model.addAttribute("group", group);
return "detailsNoMember"; return "detailsNoMember";
@ -176,19 +202,20 @@ public class Gruppen2Controller {
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/leaveGroup") @PostMapping("/leaveGroup")
public String pLeaveGroup(KeycloakAuthenticationToken token, @RequestParam (value="group_id") Long id) throws EventException { public String pLeaveGroup(KeycloakAuthenticationToken token, @RequestParam("group_id") Long groupId) throws EventException {
Account account = keyCloakService.createAccountFromPrincipal(token); Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail()); User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
controllerService.deleteUser(user.getUser_id(), id); controllerService.deleteUser(user.getId(), groupId);
return "redirect:/gruppen2/"; return "redirect:/gruppen2/";
} }
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
@GetMapping("/details/members/{id}") @GetMapping("/details/members/{id}")
public String editMembers(Model model, KeycloakAuthenticationToken token, @PathVariable (value="id") Long id) throws EventException { public String editMembers(Model model, KeycloakAuthenticationToken token, @PathVariable("id") Long groupId) throws EventException {
Account account = keyCloakService.createAccountFromPrincipal(token); Account account = keyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(id); Group group = userService.getGroupById(groupId);
if (group.getRoles().get(account.getName()) == Role.ADMIN) { if (group.getRoles().get(account.getName()) == Role.ADMIN) {
model.addAttribute("account", account);
model.addAttribute("members", group.getMembers()); model.addAttribute("members", group.getMembers());
model.addAttribute("group", group); model.addAttribute("group", group);
model.addAttribute("admin", Role.ADMIN); model.addAttribute("admin", Role.ADMIN);
@ -200,22 +227,17 @@ public class Gruppen2Controller {
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
@PostMapping("/details/members/changeRole") @PostMapping("/details/members/changeRole")
public String changeRole(KeycloakAuthenticationToken token, @RequestParam (value = "group_id") Long group_id, public String changeRole(KeycloakAuthenticationToken token, @RequestParam("group_id") Long groupId,
@RequestParam (value = "user_id") String user_id) throws EventException { @RequestParam("user_id") String userId) throws EventException {
controllerService.updateRole(user_id, group_id); controllerService.updateRole(userId, groupId);
return "redirect:/gruppen2/details/members/" + group_id; return "redirect:/gruppen2/details/members/" + groupId;
} }
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
@PostMapping("/details/members/deleteUser") @PostMapping("/details/members/deleteUser")
public String deleteUser(KeycloakAuthenticationToken token,@RequestParam (value = "group_id") Long group_id, public String deleteUser(KeycloakAuthenticationToken token, @RequestParam("group_id") Long groupId,
@RequestParam (value = "user_id") String user_id) throws EventException { @RequestParam("user_id") String userId) throws EventException {
controllerService.deleteUser(user_id, group_id); controllerService.deleteUser(userId, groupId);
return "redirect:/gruppen2/details/members/" + group_id; return "redirect:/gruppen2/details/members/" + groupId;
}
@GetMapping("*")
public String defaultLink() {
return "error";
} }
} }

View File

@ -18,4 +18,9 @@ public class MopsController {
request.logout(); request.logout();
return "redirect:/gruppen2/"; return "redirect:/gruppen2/";
} }
@GetMapping("*")
public String defaultLink() {
return "errorRenameLater";
}
} }

View File

@ -1,7 +1,5 @@
package mops.gruppen2.domain; package mops.gruppen2.domain;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -13,17 +11,15 @@ import java.util.Map;
/** /**
* Repräsentiert den aggregierten Zustand einer Gruppe. * Repräsentiert den aggregierten Zustand einer Gruppe.
*/ */
@EqualsAndHashCode(callSuper = false)
@Getter @Getter
@Setter @Setter
@AllArgsConstructor
public class Group { public class Group {
private final List<User> members;
private final Map<String, Role> roles;
private Long id; private Long id;
private String title; private String title;
private String description; private String description;
private final List<User> members;
private final Map<String, Role> roles;
private GroupType type; private GroupType type;
private Visibility visibility; private Visibility visibility;
private Long parent; private Long parent;

View File

@ -1,17 +1,16 @@
package mops.gruppen2.domain; package mops.gruppen2.domain;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.Getter;
@Data @Getter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(exclude = {"givenname", "familyname", "email"}) @EqualsAndHashCode(exclude = {"givenname", "familyname", "email"})
public class User { public class User {
String user_id;
String givenname; private final String id;
String familyname; private final String givenname;
String email; private final String familyname;
private final String email;
} }

View File

@ -0,0 +1,16 @@
package mops.gruppen2.domain.api;
import lombok.AllArgsConstructor;
import mops.gruppen2.domain.Group;
import java.util.List;
/**
* Kombiniert den Status und die Gruppenliste zur ausgabe über die API.
*/
@AllArgsConstructor
public class GroupRequestWrapper {
private final Long status;
private final List<Group> groupList;
}

View File

@ -1,16 +0,0 @@
package mops.gruppen2.domain.apiWrapper;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group;
import java.util.List;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class UpdatedGroupRequestMapper {
private Long status;
private List<Group> groupList;
}

View File

@ -1,12 +1,13 @@
package mops.gruppen2.domain.dto; package mops.gruppen2.domain.dto;
import lombok.Data; import lombok.Value;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.relational.core.mapping.Table;
@Table("event") @Table("event")
@Data @Value
public class EventDTO { public class EventDTO {
@Id @Id
Long event_id; Long event_id;
Long group_id; Long group_id;

View File

@ -1,14 +1,14 @@
package mops.gruppen2.domain.dto; package mops.gruppen2.domain.dto;
import lombok.AllArgsConstructor; import lombok.Value;
import lombok.Data;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.relational.core.mapping.Table;
@SuppressWarnings("checkstyle:membername")
@Table("invite") @Table("invite")
@Data @Value
@AllArgsConstructor
public class InviteLinkDTO { public class InviteLinkDTO {
@Id @Id
Long link_id; Long link_id;
Long group_id; Long group_id;

View File

@ -3,26 +3,26 @@ package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Exceptions.UserAlreadyExistsException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role; import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User; import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
/** /**
* Fügt einen einzelnen Nutzer einer Gruppe hinzu. * Fügt einen einzelnen Nutzer einer Gruppe hinzu.
*/ */
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor // For Jackson
public class AddUserEvent extends Event { public class AddUserEvent extends Event {
private String givenname; private String givenname;
private String familyname; private String familyname;
private String email; private String email;
public AddUserEvent(Long group_id, String user_id, String givenname, String familyname, String email) { public AddUserEvent(Long groupId, String userId, String givenname, String familyname, String email) {
super(group_id, user_id); super(groupId, userId);
this.givenname = givenname; this.givenname = givenname;
this.familyname = familyname; this.familyname = familyname;
this.email = email; this.email = email;
@ -30,13 +30,13 @@ public class AddUserEvent extends Event {
@Override @Override
public void applyEvent(Group group) throws EventException { public void applyEvent(Group group) throws EventException {
User user = new User(this.user_id, this.givenname, this.familyname, this.email); User user = new User(this.userId, this.givenname, this.familyname, this.email);
if (group.getMembers().contains(user)) { if (group.getMembers().contains(user)) {
throw new UserAlreadyExistsException(this.getClass().toString()); throw new UserAlreadyExistsException(this.getClass().toString());
} }
group.getMembers().add(user); group.getMembers().add(user);
group.getRoles().put(user_id, Role.MEMBER); group.getRoles().put(userId, Role.MEMBER);
} }
} }

View File

@ -9,23 +9,23 @@ import mops.gruppen2.domain.Visibility;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor // For Jackson
public class CreateGroupEvent extends Event { public class CreateGroupEvent extends Event {
private Visibility groupVisibility; private Visibility groupVisibility;
private Long groupParent; private Long groupParent;
private GroupType groupType; private GroupType groupType;
public CreateGroupEvent(Long group_id, String user_id, Long parent, GroupType type, Visibility visibility) { public CreateGroupEvent(Long groupId, String userId, Long parent, GroupType type, Visibility visibility) {
super(group_id, user_id); super(groupId, userId);
this.groupParent = parent; this.groupParent = parent;
this.groupType = type; this.groupType = type;
this.groupVisibility = visibility; this.groupVisibility = visibility;
} }
@Override @Override
public void applyEvent(Group group) { public void apply(Group group) {
group.setId(this.group_id); group.setId(this.groupId);
group.setParent(this.groupParent); group.setParent(this.groupParent);
group.setType(this.groupType); group.setType(this.groupType);
group.setVisibility(this.groupVisibility); group.setVisibility(this.groupVisibility);

View File

@ -1,15 +1,15 @@
package mops.gruppen2.domain.event; package mops.gruppen2.domain.event;
import lombok.EqualsAndHashCode; import lombok.Getter;
import lombok.Value; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
@EqualsAndHashCode(callSuper = true) @Getter
@Value @NoArgsConstructor // For Jackson
public class DeleteGroupEvent extends Event { public class DeleteGroupEvent extends Event {
public DeleteGroupEvent(long group_id, String user_id) { public DeleteGroupEvent(Long groupId, String userId) {
super(group_id, user_id); super(groupId, userId);
} }
@Override @Override

View File

@ -2,28 +2,28 @@ package mops.gruppen2.domain.event;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Exceptions.UserNotFoundException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User; import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.UserNotFoundException;
/** /**
* Entfernt ein einzelnes Mitglied einer Gruppe. * Entfernt ein einzelnes Mitglied einer Gruppe.
*/ */
@Getter @Getter
@NoArgsConstructor @NoArgsConstructor // For Jackson
public class DeleteUserEvent extends Event { public class DeleteUserEvent extends Event {
public DeleteUserEvent(Long group_id, String user_id) { public DeleteUserEvent(Long groupId, String userId) {
super(group_id, user_id); super(groupId, userId);
} }
@Override @Override
public void applyEvent(Group group) throws EventException { public void applyEvent(Group group) throws EventException {
for (User user : group.getMembers()) { for (User user : group.getMembers()) {
if (user.getUser_id().equals(this.user_id)) { if (user.getId().equals(this.userId)) {
group.getMembers().remove(user); group.getMembers().remove(user);
group.getRoles().remove(user.getUser_id()); group.getRoles().remove(user.getId());
return; return;
} }
} }

View File

@ -5,13 +5,11 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Exceptions.GroupIdMismatchException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.EventException;
@JsonTypeInfo( @JsonTypeInfo(
include = JsonTypeInfo.As.PROPERTY,
use = JsonTypeInfo.Id.NAME, use = JsonTypeInfo.Id.NAME,
property = "type" property = "type"
) )
@ -24,13 +22,12 @@ import mops.gruppen2.domain.Group;
@JsonSubTypes.Type(value = UpdateRoleEvent.class, name = "UpdateRoleEvent"), @JsonSubTypes.Type(value = UpdateRoleEvent.class, name = "UpdateRoleEvent"),
}) })
@Getter @Getter
@Setter @NoArgsConstructor
@NoArgsConstructor // Needed by Lombok in Subclasses
@AllArgsConstructor @AllArgsConstructor
public abstract class Event { public abstract class Event {
protected Long group_id; protected Long groupId;
protected String user_id; protected String userId;
public void apply(Group group) throws EventException { public void apply(Group group) throws EventException {
checkGroupIdMatch(group.getId()); checkGroupIdMatch(group.getId());
@ -39,8 +36,8 @@ public abstract class Event {
protected abstract void applyEvent(Group group) throws EventException; protected abstract void applyEvent(Group group) throws EventException;
private void checkGroupIdMatch(Long group_id) { private void checkGroupIdMatch(Long groupId) {
if (group_id == null || this.group_id.equals(group_id)) { if (groupId == null || this.group_id.equals(groupId)) {
return; return;
} }

View File

@ -11,13 +11,13 @@ import mops.gruppen2.domain.Group;
*/ */
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor // For Jackson
public class UpdateGroupDescriptionEvent extends Event { public class UpdateGroupDescriptionEvent extends Event {
private String newGroupDescription; private String newGroupDescription;
public UpdateGroupDescriptionEvent(Long group_id, String user_id, String newGroupDescription) { public UpdateGroupDescriptionEvent(Long groupId, String userId, String newGroupDescription) {
super(group_id, user_id); super(groupId, userId);
this.newGroupDescription = newGroupDescription; this.newGroupDescription = newGroupDescription;
} }

View File

@ -11,13 +11,13 @@ import mops.gruppen2.domain.Group;
*/ */
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor // For Jackson
public class UpdateGroupTitleEvent extends Event { public class UpdateGroupTitleEvent extends Event {
private String newGroupTitle; private String newGroupTitle;
public UpdateGroupTitleEvent(Long group_id, String user_id, String newGroupTitle) { public UpdateGroupTitleEvent(Long groupId, String userId, String newGroupTitle) {
super(group_id, user_id); super(groupId, userId);
this.newGroupTitle = newGroupTitle; this.newGroupTitle = newGroupTitle;
} }

View File

@ -3,29 +3,28 @@ package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Exceptions.UserNotFoundException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role; import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.exception.UserNotFoundException;
/** /**
* Aktualisiert die Gruppenrolle eines Teilnehmers. * Aktualisiert die Gruppenrolle eines Teilnehmers.
*/ */
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor // For Jackson
public class UpdateRoleEvent extends Event { public class UpdateRoleEvent extends Event {
private Role newRole; private Role newRole;
public UpdateRoleEvent(Long group_id, String user_id, Role newRole) { public UpdateRoleEvent(Long groupId, String userId, Role newRole) {
super(group_id, user_id); super(groupId, userId);
this.newRole = newRole; this.newRole = newRole;
} }
@Override @Override
public void applyEvent(Group group) throws UserNotFoundException { public void applyEvent(Group group) throws UserNotFoundException {
if (group.getRoles().containsKey(user_id)) { if (group.getRoles().containsKey(this.userId)) {
group.getRoles().put(this.user_id, this.newRole); group.getRoles().put(this.userId, this.newRole);
} }
throw new UserNotFoundException(this.getClass().toString()); throw new UserNotFoundException(this.getClass().toString());

View File

@ -1,4 +1,4 @@
package mops.gruppen2.domain.Exceptions; package mops.gruppen2.domain.exception;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;

View File

@ -0,0 +1,8 @@
package mops.gruppen2.domain.exception;
public class UserAlreadyExistsException extends EventException {
public UserAlreadyExistsException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,8 @@
package mops.gruppen2.domain.exception;
public class UserNotFoundException extends EventException {
public UserNotFoundException(String msg) {
super(msg);
}
}

View File

@ -10,11 +10,12 @@ import java.util.List;
@Repository @Repository
public interface EventRepository extends CrudRepository<EventDTO, Long> { public interface EventRepository extends CrudRepository<EventDTO, Long> {
@Query("select distinct group_id from event where user_id =:id") @Query("select distinct group_id from event where user_id =:id")
List<Long> findGroup_idsWhereUser_id(@Param("id") String user_id); List<Long> findGroup_idsWhereUser_id(@Param("id") String userId);
@Query("select * from event where group_id =:id") @Query("select * from event where group_id =:id")
List<EventDTO> findEventDTOByGroup_id(@Param("id") Long group_id); List<EventDTO> findEventDTOByGroup_id(@Param("id") Long groupId);
//@Query("SELECT * FROM event WHERE event_id > ?#{[0]}") //@Query("SELECT * FROM event WHERE event_id > ?#{[0]}")
//Iterable<EventDTO> findNewEventSinceStatus(@Param("status") Long status); //Iterable<EventDTO> findNewEventSinceStatus(@Param("status") Long status);
@ -23,14 +24,14 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
List<Long> findGroup_idsWhereVisibility(@Param("vis") Boolean visibility); List<Long> findGroup_idsWhereVisibility(@Param("vis") Boolean visibility);
@Query("SELECT DISTINCT group_id FROM event WHERE event_id > :status") @Query("SELECT DISTINCT group_id FROM event WHERE event_id > :status")
public List<Long> findNewEventSinceStatus(@Param("status") Long status); List<Long> findNewEventSinceStatus(@Param("status") Long status);
@Query("SELECT * FROM event WHERE group_id IN (:groupIds) ") @Query("SELECT * FROM event WHERE group_id IN (:groupIds) ")
public List<EventDTO> findAllEventsOfGroups(@Param("groupIds") List<Long> groupIds); List<EventDTO> findAllEventsOfGroups(@Param("groupIds") List<Long> groupIds);
@Query("SELECT MAX(event_id) FROM event") @Query("SELECT MAX(event_id) FROM event")
public Long getHighesEvent_ID(); Long getHighesEvent_ID();
@Query("SELECT MAX(group_id) FROM event") @Query("SELECT MAX(group_id) FROM event")
public Long getMaxGroupID(); Long getMaxGroupID();
} }

View File

@ -1,16 +1,16 @@
package mops.gruppen2.security; package mops.gruppen2.security;
import java.util.Set; import lombok.Value;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter import java.util.Set;
@AllArgsConstructor
@Value
public class Account { public class Account {
private final String name; //user_id
private final String email; String email;
private final String image; String image;
private final String givenname; String name; //user_id
private final String familyname; String givenname;
private final Set<String> roles; String familyname;
Set<String> roles;
} }

View File

@ -16,39 +16,30 @@ import org.springframework.web.client.RestTemplate;
@Configuration @Configuration
public class KeycloakConfig { public class KeycloakConfig {
@Value("${keycloak.resource}")
private String clientId;
@Value("${keycloak.credentials.secret}")
private String clientSecret;
@Value("${hhu_keycloak.token-uri}")
private String tokenUri;
@Bean @Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() { public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver(); return new KeycloakSpringBootConfigResolver();
} }
@Value("${keycloak.resource}")
private String clientId;
@Value("${keycloak.credentials.secret}")
private String clientSecret;
@Value("${hhu_keycloak.token-uri}")
private String tokenUri;
@Bean @Bean
public RestTemplate serviceAccountRestTemplate() { public RestTemplate serviceAccountRestTemplate() {
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails(); ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setGrantType(OAuth2Constants.CLIENT_CREDENTIALS); resourceDetails.setGrantType(OAuth2Constants.CLIENT_CREDENTIALS);
resourceDetails.setAccessTokenUri(tokenUri); resourceDetails.setAccessTokenUri(tokenUri);
resourceDetails.setClientId(clientId); resourceDetails.setClientId(clientId);
resourceDetails.setClientSecret(clientSecret); resourceDetails.setClientSecret(clientSecret);
return new OAuth2RestTemplate(resourceDetails); return new OAuth2RestTemplate(resourceDetails);
} }
} }

View File

@ -84,5 +84,6 @@ class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
jsr250Enabled = true) jsr250Enabled = true)
public static class MethodSecurityConfig public static class MethodSecurityConfig
extends GlobalMethodSecurityConfiguration { extends GlobalMethodSecurityConfiguration {
} }
} }

View File

@ -1,14 +1,15 @@
package mops.gruppen2.service; package mops.gruppen2.service;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.apiWrapper.UpdatedGroupRequestMapper; import mops.gruppen2.domain.api.GroupRequestWrapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@Service @Service
public class APIFormatterService { public class APIFormatterService {
static public UpdatedGroupRequestMapper wrapp(Long status, List<Group> groupList){
return new UpdatedGroupRequestMapper(status, groupList); public static GroupRequestWrapper wrap(Long status, List<Group> groupList) {
return new GroupRequestWrapper(status, groupList);
} }
} }

View File

@ -1,8 +1,18 @@
package mops.gruppen2.service; package mops.gruppen2.service;
import mops.gruppen2.domain.Exceptions.EventException; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.*; import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.event.*; import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.domain.event.AddUserEvent;
import mops.gruppen2.domain.event.CreateGroupEvent;
import mops.gruppen2.domain.event.DeleteGroupEvent;
import mops.gruppen2.domain.event.DeleteUserEvent;
import mops.gruppen2.domain.event.UpdateGroupDescriptionEvent;
import mops.gruppen2.domain.event.UpdateGroupTitleEvent;
import mops.gruppen2.domain.event.UpdateRoleEvent;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.security.Account; import mops.gruppen2.security.Account;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -14,7 +24,6 @@ import java.util.UUID;
public class ControllerService { public class ControllerService {
private final EventService eventService; private final EventService eventService;
private final UserService userService; private final UserService userService;
private final InviteLinkRepositoryService inviteLinkRepositoryService; private final InviteLinkRepositoryService inviteLinkRepositoryService;
@ -35,86 +44,90 @@ public class ControllerService {
*/ */
public void createGroup(Account account, String title, String description, Boolean visibility) throws EventException { public void createGroup(Account account, String title, String description, Boolean visibility) throws EventException {
Visibility visibility1; Visibility visibility1;
Long group_id = eventService.checkGroup(); Long groupId = eventService.checkGroup();
if (visibility) { if (visibility) {
visibility1 = Visibility.PUBLIC; visibility1 = Visibility.PUBLIC;
} else { } else {
visibility1 = Visibility.PRIVATE; visibility1 = Visibility.PRIVATE;
createInviteLink(group_id); createInviteLink(groupId);
} }
CreateGroupEvent createGroupEvent = new CreateGroupEvent(group_id, account.getName(), null , GroupType.SIMPLE, visibility1); CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), null, GroupType.SIMPLE, visibility1);
eventService.saveEvent(createGroupEvent); eventService.saveEvent(createGroupEvent);
addUser(account, group_id); addUser(account, groupId);
updateTitle(account, group_id, title); updateTitle(account, groupId, title);
updateDescription(account, group_id, description); updateDescription(account, groupId, description);
updateRole(account.getName(), group_id); updateRole(account.getName(), groupId);
} }
private void createInviteLink(Long group_id) { private void createInviteLink(Long groupId) {
inviteLinkRepositoryService.saveInvite(group_id, UUID.randomUUID()); inviteLinkRepositoryService.saveInvite(groupId, UUID.randomUUID());
} }
public void addUser(Account account, Long group_id){ public void addUser(Account account, Long groupId) {
AddUserEvent addUserEvent = new AddUserEvent(group_id,account.getName(),account.getGivenname(),account.getFamilyname(),account.getEmail()); AddUserEvent addUserEvent = new AddUserEvent(groupId, account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
eventService.saveEvent(addUserEvent); eventService.saveEvent(addUserEvent);
} }
public void addUserList(List<User> users, Long group_id) { public void addUserList(List<User> users, Long groupId) {
for (User user : users) { for (User user : users) {
AddUserEvent addUserEvent = new AddUserEvent(group_id, user.getUser_id(), user.getGivenname(), user.getFamilyname(), user.getEmail()); AddUserEvent addUserEvent = new AddUserEvent(groupId, user.getId(), user.getGivenname(), user.getFamilyname(), user.getEmail());
eventService.saveEvent(addUserEvent); eventService.saveEvent(addUserEvent);
} }
} }
public void updateTitle(Account account, Long group_id, String title){ public void updateTitle(Account account, Long groupId, String title) {
UpdateGroupTitleEvent updateGroupTitleEvent = new UpdateGroupTitleEvent(group_id,account.getName(),title); UpdateGroupTitleEvent updateGroupTitleEvent = new UpdateGroupTitleEvent(groupId, account.getName(), title);
eventService.saveEvent(updateGroupTitleEvent); eventService.saveEvent(updateGroupTitleEvent);
} }
public void updateDescription(Account account, Long group_id, String description){ public void updateDescription(Account account, Long groupId, String description) {
UpdateGroupDescriptionEvent updateGroupDescriptionEvent = new UpdateGroupDescriptionEvent(group_id,account.getName(),description); UpdateGroupDescriptionEvent updateGroupDescriptionEvent = new UpdateGroupDescriptionEvent(groupId, account.getName(), description);
eventService.saveEvent(updateGroupDescriptionEvent); eventService.saveEvent(updateGroupDescriptionEvent);
} }
public void updateRole(String user_id, Long group_id) throws EventException { public void updateRole(String userId, Long groupId) throws EventException {
UpdateRoleEvent updateRoleEvent; UpdateRoleEvent updateRoleEvent;
Group group = userService.getGroupById(group_id); Group group = userService.getGroupById(groupId);
User user = null; User user = null;
for (User member : group.getMembers()) { for (User member : group.getMembers()) {
if(member.getUser_id().equals(user_id)) user = member; if (member.getId().equals(userId)) {
user = member;
}
} }
assert user != null; assert user != null;
if(group.getRoles().get(user.getUser_id()) == Role.ADMIN) { if (group.getRoles().get(user.getId()) == Role.ADMIN) {
updateRoleEvent = new UpdateRoleEvent(group_id, user.getUser_id(), Role.MEMBER); updateRoleEvent = new UpdateRoleEvent(groupId, user.getId(), Role.MEMBER);
} else { } else {
updateRoleEvent = new UpdateRoleEvent(group_id, user.getUser_id(), Role.ADMIN); updateRoleEvent = new UpdateRoleEvent(groupId, user.getId(), Role.ADMIN);
} }
eventService.saveEvent(updateRoleEvent); eventService.saveEvent(updateRoleEvent);
} }
public void deleteUser(String user_id, Long group_id) throws EventException { public void deleteUser(String userId, Long groupId) throws EventException {
Group group = userService.getGroupById(group_id); Group group = userService.getGroupById(groupId);
User user = null; User user = null;
for (User member : group.getMembers()) { for (User member : group.getMembers()) {
if(member.getUser_id().equals(user_id)) user = member; if (member.getId().equals(userId)) {
user = member;
}
} }
assert user != null; assert user != null;
DeleteUserEvent deleteUserEvent = new DeleteUserEvent(group_id, user.getUser_id()); DeleteUserEvent deleteUserEvent = new DeleteUserEvent(groupId, user.getId());
eventService.saveEvent(deleteUserEvent); eventService.saveEvent(deleteUserEvent);
} }
public void deleteGroupEvent(User user, Long group_id) { public void deleteGroupEvent(User user, Long groupId) {
DeleteGroupEvent deleteGroupEvent = new DeleteGroupEvent(group_id, user.getUser_id()); DeleteGroupEvent deleteGroupEvent = new DeleteGroupEvent(groupId, user.getId());
eventService.saveEvent(deleteGroupEvent); eventService.saveEvent(deleteGroupEvent);
} }
public void createLecture(Account account, String title, String description, Boolean visibility, List<User> users) throws EventException { public void createLecture(Account account, String title, String description, Boolean visibility, List<User> users) throws EventException {
Visibility visibility1; Visibility visibility1;
Long group_id = eventService.checkGroup(); Long groupId = eventService.checkGroup();
if (visibility) { if (visibility) {
visibility1 = Visibility.PUBLIC; visibility1 = Visibility.PUBLIC;
@ -122,14 +135,13 @@ public class ControllerService {
visibility1 = Visibility.PRIVATE; visibility1 = Visibility.PRIVATE;
} }
CreateGroupEvent createGroupEvent = new CreateGroupEvent(group_id, account.getName(), null, GroupType.LECTURE, visibility1); CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), null, GroupType.LECTURE, visibility1);
eventService.saveEvent(createGroupEvent); eventService.saveEvent(createGroupEvent);
addUser(account, group_id); addUser(account, groupId);
updateTitle(account, group_id, title); updateTitle(account, groupId, title);
updateDescription(account, group_id, description); updateDescription(account, groupId, description);
updateRole(account.getName(), group_id); updateRole(account.getName(), groupId);
addUserList(users, group_id); addUserList(users, groupId);
} }
} }

View File

@ -13,18 +13,19 @@ import java.util.List;
@Service @Service
public class EventService { public class EventService {
private final SerializationService serializationService;
private final JsonService jsonService;
private final EventRepository eventStore; private final EventRepository eventStore;
public EventService(SerializationService serializationService, EventRepository eventStore) { public EventService(JsonService jsonService, EventRepository eventStore) {
this.serializationService = serializationService; this.jsonService = jsonService;
this.eventStore = eventStore; this.eventStore = eventStore;
} }
/** /**
* sichert ein Event Objekt indem es ein EventDTO Objekt erzeugt * Erzeugt ein DTO aus einem Event und speicher es.
* *
* @param event * @param event Event, welches gespeichert wird
*/ */
public void saveEvent(Event event) { public void saveEvent(Event event) {
EventDTO eventDTO = getDTO(event); EventDTO eventDTO = getDTO(event);
@ -35,34 +36,30 @@ public class EventService {
* Erzeugt aus einem Event Objekt ein EventDTO Objekt. * Erzeugt aus einem Event Objekt ein EventDTO Objekt.
* Ist die Gruppe öffentlich, dann wird die visibility auf true gesetzt. * Ist die Gruppe öffentlich, dann wird die visibility auf true gesetzt.
* *
* @param event * @param event Event, welches in DTO übersetzt wird
* @return EventDTO * @return EventDTO Neues DTO
*/ */
public EventDTO getDTO(Event event) { public EventDTO getDTO(Event event) {
EventDTO eventDTO = new EventDTO(); boolean visibility = false;
eventDTO.setGroup_id(event.getGroup_id());
eventDTO.setUser_id(event.getUser_id());
if (event instanceof CreateGroupEvent) { if (event instanceof CreateGroupEvent) {
if (((CreateGroupEvent) event).getGroupVisibility() == Visibility.PRIVATE) { visibility = ((CreateGroupEvent) event).getGroupVisibility() == Visibility.PUBLIC;
eventDTO.setVisibility(false);
} else {
eventDTO.setVisibility(true);
}
} }
String payload = "";
try { try {
eventDTO.setEvent_payload(serializationService.serializeEvent(event)); payload = jsonService.serializeEvent(event);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
e.printStackTrace(); e.printStackTrace();
} }
return eventDTO;
return new EventDTO(null, event.getGroupId(), event.getUserId(), payload, visibility);
} }
/** /**
* Gibt die nächst höhere groupID zurück die belegt werden kann. * Gibt die nächst höhere groupID zurück die belegt werden kann.
* Gibt 1 zurück, falls keine Gruppe vorhanden ist. * Gibt 1 zurück, falls keine Gruppe vorhanden ist.
* *
* @return Gibt Long zurück * @return Long GruppenId
*/ */
public Long checkGroup() { public Long checkGroup() {
Long maxGroupID = eventStore.getMaxGroupID(); Long maxGroupID = eventStore.getMaxGroupID();
@ -75,10 +72,10 @@ public class EventService {
} }
/** /**
* Findet alle Events welche ab dem neuen Status hinzugekommen sind * Findet alle Events welche ab dem neuen Status hinzugekommen sind.
* *
* @param status * @param status Die Id des zuletzt gespeicherten Events
* @return Liste von Events * @return Liste von neueren Events
*/ */
public List<Event> getNewEvents(Long status) { public List<Event> getNewEvents(Long status) {
List<Long> groupIdsThatChanged = eventStore.findNewEventSinceStatus(status); List<Long> groupIdsThatChanged = eventStore.findNewEventSinceStatus(status);
@ -88,9 +85,9 @@ public class EventService {
} }
/** /**
* Erzeugt aus einer Liste von eventDTOs eine Liste von Events * Erzeugt aus einer Liste von eventDTOs eine Liste von Events.
* *
* @param eventDTOS * @param eventDTOS Liste von DTOs
* @return Liste von Events * @return Liste von Events
*/ */
public List<Event> translateEventDTOs(Iterable<EventDTO> eventDTOS) { public List<Event> translateEventDTOs(Iterable<EventDTO> eventDTOS) {
@ -98,7 +95,7 @@ public class EventService {
for (EventDTO eventDTO : eventDTOS) { for (EventDTO eventDTO : eventDTOS) {
try { try {
events.add(serializationService.deserializeEvent(eventDTO.getEvent_payload())); events.add(jsonService.deserializeEvent(eventDTO.getEvent_payload()));
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -107,12 +104,12 @@ public class EventService {
} }
/** /**
* Sichert eine Liste von Event Objekten mithilfe der Methode saveEvent(Event event) * Sichert eine Liste von Event Objekten mithilfe der Methode saveEvent(Event event).
* *
* @param createGroupEvents Liste von Event Objekten * @param eventList Liste von Event Objekten
*/ */
public void saveEventList(List<Event> createGroupEvents) { public void saveEventList(List<Event> eventList) {
for (Event event : createGroupEvents) { for (Event event : eventList) {
saveEvent(event); saveEvent(event);
} }
} }

View File

@ -1,9 +1,9 @@
package mops.gruppen2.service; package mops.gruppen2.service;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.dto.EventDTO; import mops.gruppen2.domain.dto.EventDTO;
import mops.gruppen2.domain.event.Event; import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.repository.EventRepository; import mops.gruppen2.repository.EventRepository;
import mops.gruppen2.security.Account; import mops.gruppen2.security.Account;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -24,81 +24,77 @@ public class GroupService {
this.eventRepository = eventRepository; this.eventRepository = eventRepository;
} }
/** Sucht in der DB alle Zeilen raus welche eine der Gruppen_ids hat. /**
* Sucht in der DB alle Zeilen raus welche eine der Gruppen_ids hat.
* Wandelt die Zeilen in Events um und gibt davon eine Liste zurück. * Wandelt die Zeilen in Events um und gibt davon eine Liste zurück.
* *
* @param group_ids * @param groupIds Liste an IDs
* @return * @return Liste an Events
*/ */
public List<Event> getGroupEvents(List<Long> group_ids) { public List<Event> getGroupEvents(List<Long> groupIds) {
List<EventDTO> eventDTOS = new ArrayList<>(); List<EventDTO> eventDTOS = new ArrayList<>();
for (Long group_id: group_ids) { for (Long groupId : groupIds) {
eventDTOS.addAll(eventRepository.findEventDTOByGroup_id(group_id)); eventDTOS.addAll(eventRepository.findEventDTOByGroup_id(groupId));
} }
return eventService.translateEventDTOs(eventDTOS); return eventService.translateEventDTOs(eventDTOS);
} }
/** Erzeugt eine neue Map wo Gruppen aus den Events erzeugt und den Gruppen_ids zugeordnet werden. /**
* Erzeugt eine neue Map wo Gruppen aus den Events erzeugt und den Gruppen_ids zugeordnet werden.
* Die Gruppen werden als Liste zurückgegeben * Die Gruppen werden als Liste zurückgegeben
* *
* @param events * @param events Liste an Events
* @return * @return Liste an Projizierten Gruppen
* @throws EventException * @throws EventException Projektionsfehler
*/ */
public List<Group> projectEventList(List<Event> events) throws EventException { public List<Group> projectEventList(List<Event> events) throws EventException {
Map<Long, Group> groupMap = new HashMap<>(); Map<Long, Group> groupMap = new HashMap<>();
for (Event event : events) { for (Event event : events) {
Group group = getOrCreateGroup(groupMap, event.getGroup_id()); Group group = getOrCreateGroup(groupMap, event.getGroupId());
event.apply(group); event.apply(group);
} }
return new ArrayList<>(groupMap.values()); return new ArrayList<>(groupMap.values());
} }
/** guckt in der Map anhand der Id nach ob die Gruppe schon in der Map vorhanden ist, wenn nicht wird eine neue private Group getOrCreateGroup(Map<Long, Group> groups, long groupId) {
* Gruppe erzeugt if (!groups.containsKey(groupId)) {
groups.put(groupId, new Group());
}
return groups.get(groupId);
}
private List<Long> removeUserGroups(List<Long> groupIds, List<Long> userGroups) {
for (Long groupId : userGroups) {
groupIds.remove(groupId);
}
return groupIds;
}
/**
* Sucht alle Zeilen in der DB mit visibility=true.
* Erstellt eine Liste aus öffentlichen Gruppen (ohen bereits beigetretenen Gruppen).
* *
* @param groups * @return Liste von projizierten Gruppen
* @param group_id * @throws EventException Projektionsfehler
* @return
*/ */
private Group getOrCreateGroup(Map<Long, Group> groups, long group_id) { public List<Group> getAllGroupWithVisibilityPublic(String userId) throws EventException {
if (!groups.containsKey(group_id)) { List<Long> groupIds = removeUserGroups(eventRepository.findGroup_idsWhereVisibility(Boolean.TRUE), eventRepository.findGroup_idsWhereUser_id(userId));
groups.put(group_id, new Group()); List<EventDTO> eventDTOS = eventRepository.findAllEventsOfGroups(groupIds);
}
return groups.get(group_id);
}
private List<Long> removeUserGroups(List<Long> group_ids, List<Long> user_groups) {
for (Long group_id: user_groups) {
group_ids.remove(group_id);
}
return group_ids;
}
/**
* sucht alle Zeilen in der DB wo die Visibility true ist und entfernt alle Gruppen des Users.
* Erstellt eine Liste aus Gruppen.
* @return
* @throws EventException
*/
public List<Group> getAllGroupWithVisibilityPublic(String user_id) throws EventException {
List<Long> group_ids = removeUserGroups(eventRepository.findGroup_idsWhereVisibility(Boolean.TRUE), eventRepository.findGroup_idsWhereUser_id(user_id));
List<EventDTO> eventDTOS = eventRepository.findAllEventsOfGroups(group_ids);
List<Event> events = eventService.translateEventDTOs(eventDTOS); List<Event> events = eventService.translateEventDTOs(eventDTOS);
List<Group> groups = projectEventList(events); return projectEventList(events);
return groups;
} }
/** /**
* Filtert alle öffentliche Gruppen nach dem suchbegriff und gibt diese als Liste von Gruppen zurück. * Filtert alle öffentliche Gruppen nach dem Suchbegriff und gibt diese als Liste von Gruppen zurück.
* Groß und kleinschreibung wird beachtet. * Groß und Kleinschreibung wird nicht beachtet.
* @param search *
* @return * @param search Der Suchstring
* @throws EventException * @return Liste von projizierten Gruppen
* @throws EventException Projektionsfehler
*/ */
public List<Group> findGroupWith(String search, Account account) throws EventException { public List<Group> findGroupWith(String search, Account account) throws EventException {
List<Group> groups = new ArrayList<>(); List<Group> groups = new ArrayList<>();

View File

@ -19,8 +19,8 @@ public class InviteLinkRepositoryService {
return inviteLinkRepository.findGroupIdByLink(link); return inviteLinkRepository.findGroupIdByLink(link);
} }
public void saveInvite(Long group_id, UUID link) { public void saveInvite(Long groupId, UUID link) {
inviteLinkRepository.save(new InviteLinkDTO(null, group_id, link.toString())); inviteLinkRepository.save(new InviteLinkDTO(null, groupId, link.toString()));
} }
} }

View File

@ -3,30 +3,20 @@ package mops.gruppen2.service;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import mops.gruppen2.domain.event.Event; import mops.gruppen2.domain.event.Event;
import mops.gruppen2.repository.EventRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
* Übersetzt JSON-Event-Payloads zu Java-Event-Repräsentationen und zurück. * Übersetzt JSON-Event-Payloads zu Java-Event-Repräsentationen und zurück.
*/ */
@Service @Service
public class SerializationService { public class JsonService {
private final EventRepository eventStore;
private final Logger log = LoggerFactory.getLogger(SerializationService.class);
public SerializationService(EventRepository eventStore) {
this.eventStore = eventStore;
}
/** /**
* Übersetzt mithilfe der Jackson-Library eine Java-Event-Repräsentation zu einem JSON-Event-Payload. * Übersetzt mithilfe der Jackson-Library eine Java-Event-Repräsentation zu einem JSON-Event-Payload.
* *
* @param event Java-Event-Repräsentation * @param event Java-Event-Repräsentation
* @return JSON-Event-Payload als String * @return JSON-Event-Payload als String
* @throws JsonProcessingException * @throws JsonProcessingException Bei JSON Fehler
*/ */
public String serializeEvent(Event event) throws JsonProcessingException { public String serializeEvent(Event event) throws JsonProcessingException {
@ -39,7 +29,7 @@ public class SerializationService {
* *
* @param json JSON-Event-Payload als String * @param json JSON-Event-Payload als String
* @return Java-Event-Repräsentation * @return Java-Event-Repräsentation
* @throws JsonProcessingException * @throws JsonProcessingException Bei JSON Fehler
*/ */
public Event deserializeEvent(String json) throws JsonProcessingException { public Event deserializeEvent(String json) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();

View File

@ -1,21 +1,21 @@
package mops.gruppen2.service; package mops.gruppen2.service;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Exceptions.GroupNotFoundException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User; import mops.gruppen2.domain.User;
import mops.gruppen2.domain.event.Event; import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.repository.EventRepository; import mops.gruppen2.repository.EventRepository;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
//Hallo //Hallo
@Service @Service
public class UserService { public class UserService {
final EventRepository eventRepository; private final EventRepository eventRepository;
final GroupService groupService; private final GroupService groupService;
public UserService(EventRepository eventRepository, GroupService groupService) { public UserService(EventRepository eventRepository, GroupService groupService) {
this.eventRepository = eventRepository; this.eventRepository = eventRepository;
@ -25,8 +25,8 @@ public class UserService {
//Test nötig?? //Test nötig??
public List<Group> getUserGroups(User user) throws EventException { public List<Group> getUserGroups(User user) throws EventException {
List<Long> group_ids = eventRepository.findGroup_idsWhereUser_id(user.getUser_id()); List<Long> groupIds = eventRepository.findGroup_idsWhereUser_id(user.getId());
List<Event> events = groupService.getGroupEvents(group_ids); List<Event> events = groupService.getGroupEvents(groupIds);
List<Group> groups = groupService.projectEventList(events); List<Group> groups = groupService.projectEventList(events);
List<Group> newGroups = new ArrayList<>(); List<Group> newGroups = new ArrayList<>();
for (Group group : groups) { for (Group group : groups) {
@ -37,15 +37,15 @@ public class UserService {
return newGroups; return newGroups;
} }
public Group getGroupById(Long group_id) throws EventException { public Group getGroupById(Long groupId) throws EventException {
List<Long> group_ids = new ArrayList<>(); List<Long> groupIds = new ArrayList<>();
group_ids.add(group_id); group_ids.add(groupId);
try { try {
List<Event> events = groupService.getGroupEvents(group_ids); List<Event> events = groupService.getGroupEvents(groupIds);
return groupService.projectEventList(events).get(0); return groupService.projectEventList(events).get(0);
} catch (IndexOutOfBoundsException e) { } catch (IndexOutOfBoundsException e) {
throw new GroupNotFoundException("Gruppe nicht gefunden"); throw new GroupNotFoundException(this.getClass().toString());
} }
} }
} }

View File

@ -1,4 +1,3 @@
server.port=8080
application.name=gruppen2 application.name=gruppen2
logging.pattern.console=[${application.name}],%magenta(%-5level), %d{dd-MM-yyyy HH:mm:ss.SSS}, %highlight(%msg),%thread,%logger.%M%n logging.pattern.console=[${application.name}],%magenta(%-5level), %d{dd-MM-yyyy HH:mm:ss.SSS}, %highlight(%msg),%thread,%logger.%M%n
spring.datasource.url=jdbc:h2:mem:blogdb spring.datasource.url=jdbc:h2:mem:blogdb
@ -16,7 +15,6 @@ keycloak.resource=gruppenfindung
keycloak.credentials.secret=fc6ebf10-8c63-4e71-a667-4eae4e8209a1 keycloak.credentials.secret=fc6ebf10-8c63-4e71-a667-4eae4e8209a1
keycloak.verify-token-audience=true keycloak.verify-token-audience=true
keycloak.use-resource-role-mappings=true keycloak.use-resource-role-mappings=true
keycloak.autodetect-bearer-only=true keycloak.autodetect-bearer-only=true
keycloak.confidential-port=443 keycloak.confidential-port=443
server.error.include-stacktrace=always server.error.include-stacktrace=always

View File

@ -1,5 +1,4 @@
application.name=gruppen2 application.name=gruppen2
logging.pattern.console=[${application.name}],%magenta(%-5level), %d{dd-MM-yyyy HH:mm:ss.SSS}, %highlight(%msg),%thread,%logger.%M%n logging.pattern.console=[${application.name}],%magenta(%-5level), %d{dd-MM-yyyy HH:mm:ss.SSS}, %highlight(%msg),%thread,%logger.%M%n
spring.datasource.initialization-mode=always spring.datasource.initialization-mode=always
@ -10,12 +9,10 @@ spring.datasource.password=geheim
keycloak.principal-attribute=preferred_username keycloak.principal-attribute=preferred_username
keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth
keycloak.realm=MOPS keycloak.realm=MOPS
hhu_keycloak.token-uri=https://keycloak.cs.hhu.de/auth/realms/MOPS/protocol/openid-connect/token hhu_keycloak.token-uri=https://keycloak.cs.hhu.de/auth/realms/MOPS/protocol/openid-connect/token
keycloak.resource=gruppenfindung keycloak.resource=gruppenfindung
keycloak.credentials.secret= fc6ebf10-8c63-4e71-a667-4eae4e8209a1 keycloak.credentials.secret= fc6ebf10-8c63-4e71-a667-4eae4e8209a1
keycloak.verify-token-audience=true keycloak.verify-token-audience=true
keycloak.use-resource-role-mappings=true keycloak.use-resource-role-mappings=true
keycloak.autodetect-bearer-only=true keycloak.autodetect-bearer-only=true
keycloak.confidential-port= 443 keycloak.confidential-port= 443

View File

@ -1,3 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile -- noinspection SqlNoDataSourceInspectionForFile
DROP TABLE IF EXISTS event; DROP TABLE IF EXISTS event;

View File

@ -34,23 +34,29 @@
<div class="col-10"> <div class="col-10">
<h1>Gruppenerstellung</h1> <h1>Gruppenerstellung</h1>
<form method="post" action="/gruppen2/createGroup"> <form method="post" action="/gruppen2/createGroup">
<div class="shadow p-2" style=" border: 10px solid aliceblue; background: aliceblue"> <div class="shadow p-2"
style=" border: 10px solid aliceblue; background: aliceblue">
<div class="form-group"> <div class="form-group">
<label for="titel">Titel</label> <label for="titel">Titel</label>
<input type="text" class="form-control" id="titel" th:name="title" required> <input class="form-control" id="titel" required th:name="title"
type="text">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="beschreibung">Beschreibung</label> <label for="beschreibung">Beschreibung</label>
<textarea th:name="beschreibung" class="form-control" id="beschreibung" rows="3" required></textarea> <textarea class="form-control" id="beschreibung" required
rows="3" th:name="beschreibung"></textarea>
</div> </div>
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input type="checkbox" id="visibility" class="custom-control-input" th:name="visibility"> <input class="custom-control-input" id="visibility" th:name="visibility"
<label class="custom-control-label" for="visibility">Private Gruppe</label> type="checkbox">
<label class="custom-control-label" for="visibility">Private
Gruppe</label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="sel1"></label> <label for="sel1"></label>
<select class="form-control" id="sel1"> <select class="form-control" id="sel1">
<option selected="true" disabled>--Bitte Veranstaltung auswählen--</option> <option disabled selected="true">--Bitte Veranstaltung auswählen--
</option>
<option>1</option> <option>1</option>
<option>2</option> <option>2</option>
<option>3</option> <option>3</option>
@ -58,7 +64,10 @@
</select> </select>
</div> </div>
<div class="form-group pt-4"> <div class="form-group pt-4">
<button class="btn btn-primary" type="submit" style="background: #52a1eb; border-style: none">Erstellen</button> <button class="btn btn-primary"
style="background: #52a1eb; border-style: none"
type="submit">Erstellen
</button>
</div> </div>
</div> </div>
</form> </form>

View File

@ -7,6 +7,11 @@
<title>Gruppenerstellung</title> <title>Gruppenerstellung</title>
<th:block th:fragment="headcontent"> <th:block th:fragment="headcontent">
<!-- Links, Skripts, Styles hier einfügen! --> <!-- Links, Skripts, Styles hier einfügen! -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</th:block> </th:block>
</head> </head>
<body> <body>
@ -33,38 +38,56 @@
<div class="row"> <div class="row">
<div class="col-10"> <div class="col-10">
<h1>Veranstaltung erstellen</h1> <h1>Veranstaltung erstellen</h1>
<div class="shadow p-2" style=" border: 10px solid aliceblue; background: aliceblue"> <div class="shadow p-2"
<form method="post" action="/gruppen2/createLecture" enctype="multipart/form-data"> style=" border: 10px solid aliceblue; background: aliceblue">
<form action="/gruppen2/createLecture" enctype="multipart/form-data"
method="post">
<div class="form-group"> <div class="form-group">
<label for="titel">Titel</label> <label for="titel">Titel</label>
<input type="text" class="form-control" id="titel" th:name="title" required> <input class="form-control" id="titel" required th:name="title"
type="text">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="beschreibung">Beschreibung</label> <label for="beschreibung">Beschreibung</label>
<textarea th:name="beschreibung" class="form-control" id="beschreibung" rows="3" required></textarea> <textarea class="form-control" id="beschreibung" required
rows="3" th:name="beschreibung"></textarea>
</div> </div>
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input type="checkbox" id="visibility" class="custom-control-input" th:name="visibility"> <input class="custom-control-input" id="visibility" th:name="visibility"
<label class="custom-control-label" for="visibility">Private Gruppe</label> type="checkbox">
<label class="custom-control-label" for="visibility">Private
Gruppe</label>
</div> </div>
<div class="form-group pt-4"> <div class="form-group pt-4">
<div class="row"> <div class="row">
<div class="col-10"> <div class="col">
<div class="custom-file"> <div class="custom-file">
<input type="file" class="custom-file-input" id="file" th:name="file"> <input class="custom-file-input" id="file" th:name="file"
<label class="custom-file-label" for="file">CSV Datei von Mitgliedern hochladen</label> type="file">
<label class="custom-file-label" for="file">CSV Datei von
Mitgliedern hochladen</label>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group pt-4"> <div class="form-group pt-4">
<button class="btn btn-primary" type="submit" style="background: #52a1eb; border-style: none">Erstellen</button> <button class="btn btn-primary"
style="background: #52a1eb; border-style: none"
type="submit">Erstellen
</button>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<script>
// Add the following code if you want the name of the file appear on select
$(".custom-file-input").on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
});
</script>
</main> </main>
</body> </body>
</html> </html>

View File

@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" <html lang="en"
th:replace="~{mopslayout :: html(name='Gruppenbildung', headcontent=~{:: headcontent}, navigation=~{:: navigation}, bodycontent=~{:: bodycontent})}"> th:replace="~{mopslayout :: html(name='Gruppenbildung', headcontent=~{:: headcontent}, navigation=~{:: navigation}, bodycontent=~{:: bodycontent})}"
xmlns:th="http://www.thymeleaf.org">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Gruppendetails</title> <title>Gruppendetails</title>
@ -13,16 +14,16 @@
<nav class="navigation navigation-secondary" is="mops-navigation" th:fragment="navigation"> <nav class="navigation navigation-secondary" is="mops-navigation" th:fragment="navigation">
<ul> <ul>
<li class="active"> <li class="active">
<a th:href="@{/gruppen2}" href="/">Gruppen</a> <a href="/" th:href="@{/gruppen2}">Gruppen</a>
</li> </li>
<li> <li>
<a th:href="@{/gruppen2/createGroup}" href="/createGroup">Erstellen</a> <a href="/createGroup" th:href="@{/gruppen2/createGroup}">Erstellen</a>
</li> </li>
<li> <li>
<a th:href="@{/gruppen2/findGroup}" href="/findGroup">Suche</a> <a href="/findGroup" th:href="@{/gruppen2/findGroup}">Suche</a>
</li> </li>
<li th:if="${account.getRoles().contains('orga')}"> <li th:if="${account.getRoles().contains('orga')}">
<a th:href="@{/gruppen2/createLecture}" href="/createLecture">Veranstaltung</a> <a href="/createLecture" th:href="@{/gruppen2/createLecture}">Veranstaltung</a>
</li> </li>
</ul> </ul>
</nav> </nav>
@ -30,34 +31,43 @@
<main th:fragment="bodycontent"> <main th:fragment="bodycontent">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-9 shadow-sm p-4"
<div class="col-9 shadow-sm p-4" style="border: 10px solid aliceblue; background: aliceblue"> style="border: 10px solid aliceblue; background: aliceblue">
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1> <h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
<h3> <h3>
<span class="badge badge-pill badge-dark" style="background: darkslategray" th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span> <span class="badge badge-pill badge-dark" style="background: darkslategray"
<span class="badge badge-pill badge-primary" th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span> th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span>
<span class="badge badge-pill badge-success" style="background: lightseagreen" th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span> <span class="badge badge-pill badge-primary"
th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span>
<span class="badge badge-pill badge-success" style="background: lightseagreen"
th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span>
</h3> </h3>
<br> <br>
<div class="shadow-sm p-4" style="background: white"> <div class="shadow-sm p-4" style="background: white">
<p style="overflow-wrap: break-word" th:text="${group.getDescription()}"></p> <p style="overflow-wrap: break-word" th:text="${group.getDescription()}"></p>
</div> </div>
<br> <br>
<div class="text-right btn-toolbar" style="float: right" role="toolbar"> <div class="text-right btn-toolbar" role="toolbar" style="float: right">
<button class="btn btn-primary" style="background: dodgerblue; border: none; margin: 5px"> <button class="btn btn-primary"
<a th:href="@{/gruppen2}" style="color: white">Zurück</a> style="background: dodgerblue; border: none; margin: 5px">
<a style="color: white" th:href="@{/gruppen2}">Zurück</a>
</button>
<form action="/gruppen2/leaveGroup" method="post">
<button class="btn btn-danger" style="border-style: none; margin: 5px"
th:name="group_id" th:value="${group.getId()}"
type="submit">Gruppe verlassen
</button> </button>
<form method="post" action="/gruppen2/leaveGroup">
<button th:value="${group.getId()}" th:name="group_id" class="btn btn-danger" type="submit" style="border-style: none; margin: 5px">Gruppe verlassen</button>
</form> </form>
</div> </div>
</div> </div>
<div class="col-3" style="white-space: nowrap"> <div class="col-3" style="white-space: nowrap">
<div style="display: inline-block; margin: 0"> <div style="display: inline-block; margin: 0">
<h2>Mitglieder</h2> <h2>Mitglieder</h2>
<div th:if='${group.getRoles().get(user.getUser_id()) == admin}'> <div th:if="${group.getRoles().get(user.getId()) == admin}">
<form method="get" th:action="@{/gruppen2/details/members/{id}(id=${group.getId()})}"> <form method="get"
<button class="btn btn-secondary" style="background: slategrey; float: right" > th:action="@{/gruppen2/details/members/{id}(id=${group.getId()})}">
<button class="btn btn-secondary"
style="background: slategrey; float: right">
Mitglieder bearbeiten Mitglieder bearbeiten
</button> </button>
</form> </form>
@ -66,10 +76,12 @@
<br> <br>
</div> </div>
<div> <div>
<ul th:each="member : ${group.getMembers()}" class="list-group-flush" style="background: slategrey"> <ul class="list-group-flush" style="background: slategrey"
th:each="member : ${group.getMembers()}">
<li class="list-group-item" style="background: aliceblue"> <li class="list-group-item" style="background: aliceblue">
<span th:text="${member.getUser_id()}"></span> <span th:text="${member.getUser_id()}"></span>
<span th:if='${group.getRoles().get(member.getUser_id()) == admin}' class="badge badge-success">admin</span> <span class="badge badge-success"
th:if='${group.getRoles().get(member.getUser_id()) == admin}'>admin</span>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -31,20 +31,31 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-9"> <div class="col-9">
<div class="shadow-sm p-4" style="border: 10px solid aliceblue; background: aliceblue"> <div class="shadow-sm p-4"
style="border: 10px solid aliceblue; background: aliceblue">
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1> <h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
<h3> <h3>
<span class="badge badge-pill badge-dark" style="background: darkslategray" th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span> <span class="badge badge-pill badge-dark" style="background: darkslategray"
<span class="badge badge-pill badge-primary" th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span> th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span>
<span class="badge badge-pill badge-success" style="background: lightseagreen" th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span> <span class="badge badge-pill badge-primary"
th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span>
<span class="badge badge-pill badge-success"
style="background: lightseagreen"
th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span>
</h3> </h3>
<div class="shadow-sm p-4" style="background: white"> <div class="shadow-sm p-4" style="background: white">
<p style="overflow-wrap: break-word" th:text="${group.getDescription()}"></p> <p style="overflow-wrap: break-word"
th:text="${group.getDescription()}"></p>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="text-right"> <div class="text-right">
<form method="post" action="/gruppen2/detailsBeitreten"> <form method="post" action="/gruppen2/detailsBeitreten">
<button type="submit" th:href="@{/gruppen2/detailsBeitreten(id=${group.getId()})}" th:name="id" th:value="${group.id}" class="btn btn-primary" style="border-style: none;">Gruppe beitreten</button> <button class="btn btn-primary"
style="border-style: none;"
th:href="@{/gruppen2/detailsBeitreten(id=${group.getId()})}"
th:name="id" th:value="${group.id}"
type="submit">Gruppe beitreten
</button>
</form> </form>
</div> </div>
</div> </div>

View File

@ -6,6 +6,11 @@
<title>Gruppendetails</title> <title>Gruppendetails</title>
<th:block th:fragment="headcontent"> <th:block th:fragment="headcontent">
<!-- Links, Skripts, Styles hier einfügen! --> <!-- Links, Skripts, Styles hier einfügen! -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</th:block> </th:block>
</head> </head>
<body> <body>
@ -21,6 +26,9 @@
<li> <li>
<a th:href="@{/gruppen2/findGroup}" href="/findGroup">Suche</a> <a th:href="@{/gruppen2/findGroup}" href="/findGroup">Suche</a>
</li> </li>
<li th:if="${account.getRoles().contains('orga')}">
<a th:href="@{/gruppen2/createLecture}" href="/createLecture">Veranstaltung</a>
</li>
</ul> </ul>
</nav> </nav>
</header> </header>
@ -29,6 +37,31 @@
<div class="row"> <div class="row">
<div class="col-9"> <div class="col-9">
<div class="shadow p-2" style="border: 10px solid aliceblue; background: aliceblue"> <div class="shadow p-2" style="border: 10px solid aliceblue; background: aliceblue">
<!-- absichern im controller nicht vergessen -->
<div class="form-group pt-4" th:if="${account.getRoles().contains('orga')}">
<form action="/gruppen2/details/members/addUsersFromCsv"
enctype="multipart/form-data"
method="post">
<div class="row">
<div class="col-9">
<div class="custom-file">
<input class="custom-file-input" id="file" th:name="file"
type="file">
<label class="custom-file-label" for="file">CSV Datei von
Mitgliedern hochladen</label>
</div>
</div>
<div class="col-3">
<button class="btn btn-primary"
style="background: #52a1eb; border-style: none"
th:name="group_id" th:value="${group.getId()}"
type="submit">
Mitglieder hinzufügen
</button>
</div>
</div>
</form>
</div>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
@ -46,25 +79,40 @@
<span th:if='${group.getRoles().get(member.getUser_id()) == admin}'>Admin</span> <span th:if='${group.getRoles().get(member.getUser_id()) == admin}'>Admin</span>
</td> </td>
<td> <td>
<form method="post" action="/gruppen2/details/members/changeRole"> <form action="/gruppen2/details/members/changeRole" method="post">
<input type="hidden" th:name="group_id" th:value="${group.getId()}"> <input th:name="group_id" th:value="${group.getId()}"
<input type="hidden" th:name="user_id" th:value="${member.getUser_id()}"> type="hidden">
<button type="submit" class="btn btn-warning btn-sm">Rolle ändern</button><!-- th:if --> <input th:name="user_id" th:value="${member.getUser_id()}"
type="hidden">
<button class="btn btn-warning btn-sm" type="submit">Rolle
ändern
</button><!-- th:if -->
</form> </form>
<form method="post" action="/gruppen2/details/members/deleteUser"> <form action="/gruppen2/details/members/deleteUser" method="post">
<input type="hidden" th:name="group_id" th:value="${group.getId()}"> <input th:name="group_id" th:value="${group.getId()}"
<input type="hidden" th:name="user_id" th:value="${member.getUser_id()}"> type="hidden">
<button class="btn btn-danger btn-sm">Mitglied entfernen</button> <input th:name="user_id" th:value="${member.getUser_id()}"
type="hidden">
<button class="btn btn-danger btn-sm">Mitglied entfernen
</button>
</form> </form>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<button type="button" class="btn btn-primary" style="background: #52a1eb; border-style: none"> <button class="btn btn-primary" style="background: #52a1eb; border-style: none"
type="button">
<a th:href="@{/gruppen2/details(id=${group.getId()})}" style="color: white">Fertig</a> <a th:href="@{/gruppen2/details(id=${group.getId()})}" style="color: white">Fertig</a>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<script>
// Add the following code if you want the name of the file appear on select
$(".custom-file-input").on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
});
</script>
</main> </main>

View File

@ -13,17 +13,17 @@
<nav class="navigation navigation-secondary" is="mops-navigation" th:fragment="navigation"> <nav class="navigation navigation-secondary" is="mops-navigation" th:fragment="navigation">
<ul> <ul>
<li class="active"> <li class="active">
<a th:href="@{/gruppen2}" href="/">Gruppen</a> <a href="/" th:href="@{/gruppen2}">Gruppen</a>
</li> </li>
<li> <li>
<a th:href="@{/gruppen2/createGroup}" href="/createGroup">Erstellen</a> <a href="/createGroup" th:href="@{/gruppen2/createGroup}">Erstellen</a>
</li> </li>
<li> <li>
<a th:href="@{/gruppen2/findGroup}" href="/findGroup">Suche</a> <a href="/findGroup" th:href="@{/gruppen2/findGroup}">Suche</a>
</li> </li>
<!-- Fix double point --> <!-- Fix double point -->
<li th:if="${account.getRoles().contains('orga')}"> <li th:if="${account.getRoles().contains('orga')}">
<a th:href="@{/gruppen2/createLecture}" href="/createLecture">Veranstaltung</a> <a href="/createLecture" th:href="@{/gruppen2/createLecture}">Veranstaltung</a>
</li> </li>
</ul> </ul>
</nav> </nav>
@ -36,19 +36,23 @@
<form action="/" method="get"> <form action="/" method="get">
<h3 style="color: dodgerblue; font-weight: bold;"> <h3 style="color: dodgerblue; font-weight: bold;">
<small style="font-weight: normal; color: black">Mitglied in </small> <small style="font-weight: normal; color: black">Mitglied in </small>
<small style="font-weight: bold; color: black" th:text="${gruppen.size()}"></small> <small style="font-weight: bold; color: black"
<small style="font-weight: normal; color: black" th:if='${gruppen.size()==1}'> Gruppe.</small> th:text="${gruppen.size()}"></small>
<small style="font-weight: normal; color: black" th:if='${gruppen.size()!=1}'> Gruppen.</small> <small style="font-weight: normal; color: black"
th:if='${gruppen.size()==1}'> Gruppe.</small>
<small style="font-weight: normal; color: black"
th:if='${gruppen.size()!=1}'> Gruppen.</small>
</h3> </h3>
<br> <br>
<div th:each="gruppe: ${gruppen}"> <div th:each="gruppe: ${gruppen}">
<div class="shadow-sm p-4" style="border: none; background: aliceblue"> <div class="shadow-sm p-4" style="border: none; background: aliceblue">
<h3 style="color: dodgerblue; font-weight: bold;"> <h3 style="color: dodgerblue; font-weight: bold;">
<a th:href="@{/gruppen2/details/{id}(id=${gruppe.getId()})}" th:text="${gruppe.getTitle()}"></a> <a th:href="@{/gruppen2/details/{id}(id=${gruppe.getId()})}"
th:text="${gruppe.getTitle()}"></a>
</h3> </h3>
<div class="shadow-sm p-4" style="background: white"> <div class="shadow-sm p-4" style="background: white">
<p style="overflow-wrap: break-word" th:text="${#strings.abbreviate(gruppe.getDescription(),300)}"></p> <p style="overflow-wrap: break-word"
th:text="${#strings.abbreviate(gruppe.getDescription(),300)}"></p>
</div> </div>
</div> </div>
<br> <br>

View File

@ -36,9 +36,14 @@
<div class="shadow" style="border: 10px solid aliceblue; background: aliceblue"> <div class="shadow" style="border: 10px solid aliceblue; background: aliceblue">
<div class="form-group"> <div class="form-group">
<label for="suchleiste">Suchbegriff:</label> <label for="suchleiste">Suchbegriff:</label>
<input id="suchleiste" class="form-control" placeholder="z.B. Programmieren, Lerngruppe, ..." th:name="suchbegriff" type="text"> <input class="form-control" id="suchleiste"
placeholder="z.B. Programmieren, Lerngruppe, ..."
th:name="suchbegriff" type="text">
</div> </div>
<button type="submit" class="btn btn-primary" style="background: #52a1eb; border-style: none">Suchen</button> <button class="btn btn-primary"
style="background: #52a1eb; border-style: none"
type="submit">Suchen
</button>
</div> </div>
</form> </form>
<br> <br>
@ -54,9 +59,12 @@
<tbody th:each="gruppe : ${gruppen}"> <tbody th:each="gruppe : ${gruppen}">
<tr> <tr>
<th scope="row"> <th scope="row">
<a th:href="@{/gruppen2/detailsSearch(id=${gruppe.getId()})}" th:text="${gruppe.title}">Gruppenname</a> <a th:href="@{/gruppen2/detailsSearch(id=${gruppe.getId()})}"
th:text="${gruppe.title}">Gruppenname</a>
</th> </th>
<td style="" th:text="${#strings.abbreviate(gruppe.getDescription(), 50)}">Beschreibung</td> <td style="" th:text="${#strings.abbreviate(gruppe.getDescription(), 50)}">
Beschreibung
</td>
<td th:text="${gruppe.getMembers().size()}">Mitgliederanzahl</td> <td th:text="${gruppe.getMembers().size()}">Mitgliederanzahl</td>
</tr> </tr>
</tbody> </tbody>

View File

@ -5,13 +5,12 @@ import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest; import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.lang.ArchRule;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
@AnalyzeClasses(packages = "mops.gruppen2", importOptions = { ImportOption.DoNotIncludeTests.class }) @AnalyzeClasses(packages = "mops.gruppen2", importOptions = ImportOption.DoNotIncludeTests.class)
public class ControllerTest { public class ControllerTest {
@ArchTest @ArchTest

View File

@ -2,14 +2,13 @@ package mops.gruppen2.architecture;
import com.tngtech.archunit.core.importer.ImportOption; import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.junit.AnalyzeClasses; import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchIgnore;
import com.tngtech.archunit.junit.ArchTest; import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.lang.ArchRule;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
@AnalyzeClasses(packages = "mops.gruppen2", importOptions = { ImportOption.DoNotIncludeTests.class }) @AnalyzeClasses(packages = "mops.gruppen2", importOptions = ImportOption.DoNotIncludeTests.class)
public class DomainTest { public class DomainTest {
@ArchTest @ArchTest
@ -30,11 +29,11 @@ public class DomainTest {
@ArchTest @ArchTest
public static final ArchRule exceptionClassesShouldBeInExceptionPackage = classes() public static final ArchRule exceptionClassesShouldBeInExceptionPackage = classes()
.that().haveSimpleNameEndingWith("Exception") .that().haveSimpleNameEndingWith("Exception")
.should().resideInAPackage("..domain.Exceptions.."); .should().resideInAPackage("..domain.exception..");
@ArchTest @ArchTest
public static final ArchRule classesInExceptionPackageShouldHaveExceptionInName = classes() public static final ArchRule classesInExceptionPackageShouldHaveExceptionInName = classes()
.that().resideInAPackage("..domain.Exceptions..") .that().resideInAPackage("..domain.exception..")
.should().haveSimpleNameEndingWith("Exception"); .should().haveSimpleNameEndingWith("Exception");
@ArchTest @ArchTest

View File

@ -6,10 +6,10 @@ import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.library.Architectures; import com.tngtech.archunit.library.Architectures;
@AnalyzeClasses(packages = "mops.gruppen2", importOptions = { ImportOption.DoNotIncludeTests.class }) @AnalyzeClasses(packages = "mops.gruppen2", importOptions = ImportOption.DoNotIncludeTests.class)
public class LayeredArchitectureTest { public class LayeredArchitectureTest {
private static Architectures.LayeredArchitecture layeredArchitecture = Architectures private static final Architectures.LayeredArchitecture layeredArchitecture = Architectures
.layeredArchitecture() .layeredArchitecture()
.layer("Domain").definedBy("..domain..") .layer("Domain").definedBy("..domain..")
.layer("Service").definedBy("..service") .layer("Service").definedBy("..service")

View File

@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
@AnalyzeClasses(packages = "mops.gruppen2", importOptions = { ImportOption.DoNotIncludeTests.class }) @AnalyzeClasses(packages = "mops.gruppen2", importOptions = ImportOption.DoNotIncludeTests.class)
public class RepositoryTest { public class RepositoryTest {
@ArchTest @ArchTest

View File

@ -8,7 +8,7 @@ import org.springframework.stereotype.Service;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
@AnalyzeClasses(packages = "mops.gruppen2", importOptions = { ImportOption.DoNotIncludeTests.class }) @AnalyzeClasses(packages = "mops.gruppen2", importOptions = ImportOption.DoNotIncludeTests.class)
public class ServiceTest { public class ServiceTest {
@ArchTest @ArchTest

View File

@ -1,8 +1,18 @@
package mops.gruppen2.builder; package mops.gruppen2.builder;
import com.github.javafaker.Faker; import com.github.javafaker.Faker;
import mops.gruppen2.domain.*; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.event.*; import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.domain.event.AddUserEvent;
import mops.gruppen2.domain.event.CreateGroupEvent;
import mops.gruppen2.domain.event.DeleteUserEvent;
import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.event.UpdateGroupDescriptionEvent;
import mops.gruppen2.domain.event.UpdateGroupTitleEvent;
import mops.gruppen2.domain.event.UpdateRoleEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -10,39 +20,39 @@ import java.util.List;
public class EventBuilder { public class EventBuilder {
/** /**
* Generiert ein EventLog mit mehreren Gruppen nud Usern * Generiert ein EventLog mit mehreren Gruppen nud Usern.
* *
* @param count Gruppenanzahl * @param count Gruppenanzahl
* @param membercount Gesamte Mitgliederanzahl * @param membercount Gesamte Mitgliederanzahl
* @return * @return Eventliste
*/ */
public static List<Event> completeGroups(int count, int membercount) { public static List<Event> completeGroups(int count, int membercount) {
List<Event> eventList = new ArrayList<>(); List<Event> eventList = new ArrayList<>();
for (int i = 1; i <= count; i++) { for (int i = 1; i <= count; i++) {
eventList.addAll(EventBuilder.completeGroup(i, membercount / count)); eventList.addAll(completeGroup(i, membercount / count));
} }
return eventList; return eventList;
} }
public static List<Event> completeGroup(long group_id, int membercount) { public static List<Event> completeGroup(long groupId, int membercount) {
List<Event> eventList = new ArrayList<>(); List<Event> eventList = new ArrayList<>();
eventList.add(EventBuilder.createGroupEvent(group_id)); eventList.add(createGroupEvent(groupId));
eventList.add(EventBuilder.updateGroupTitleEvent(group_id)); eventList.add(updateGroupTitleEvent(groupId));
eventList.add(EventBuilder.updateGroupDescriptionEvent(group_id)); eventList.add(updateGroupDescriptionEvent(groupId));
eventList.addAll(EventBuilder.addUserEvents(membercount, group_id)); eventList.addAll(addUserEvents(membercount, groupId));
return eventList; return eventList;
} }
public static CreateGroupEvent createGroupEvent(long group_id) { public static CreateGroupEvent createGroupEvent(long groupId) {
Faker faker = new Faker(); Faker faker = new Faker();
return new CreateGroupEvent( return new CreateGroupEvent(
group_id, groupId,
faker.random().hex(), faker.random().hex(),
null, null,
GroupType.SIMPLE, GroupType.SIMPLE,
@ -51,10 +61,10 @@ public class EventBuilder {
} }
/** /**
* Generiert mehrere CreateGroupEvents, 1 <= group_id <= count * Generiert mehrere CreateGroupEvents, 1 <= groupId <= count.
* *
* @param count Anzahl der verschiedenen Gruppen. * @param count Anzahl der verschiedenen Gruppen
* @return * @return Eventliste
*/ */
public static List<CreateGroupEvent> createGroupEvents(int count) { public static List<CreateGroupEvent> createGroupEvents(int count) {
List<CreateGroupEvent> eventList = new ArrayList<>(); List<CreateGroupEvent> eventList = new ArrayList<>();
@ -66,15 +76,15 @@ public class EventBuilder {
return eventList; return eventList;
} }
public static AddUserEvent addUserEvent(long group_id, String user_id) { public static AddUserEvent addUserEvent(long groupId, String userId) {
Faker faker = new Faker(); Faker faker = new Faker();
String firstname = faker.name().firstName(); String firstname = faker.name().firstName();
String lastname = faker.name().lastName(); String lastname = faker.name().lastName();
return new AddUserEvent( return new AddUserEvent(
group_id, groupId,
user_id, userId,
firstname, firstname,
lastname, lastname,
firstname + "." + lastname + "@mail.de" firstname + "." + lastname + "@mail.de"
@ -82,73 +92,69 @@ public class EventBuilder {
} }
/** /**
* Generiert mehrere AddUserEvents für eine Gruppe, 1 <= user_id <= count * Generiert mehrere AddUserEvents für eine Gruppe, 1 <= user_id <= count.
* *
* @param count * @param count Anzahl der Mitglieder
* @param group_id * @param groupId Gruppe, zu welcher geaddet wird
* @return * @return Eventliste
*/ */
public static List<Event> addUserEvents(int count, long group_id) { public static List<Event> addUserEvents(int count, long groupId) {
List<Event> eventList = new ArrayList<>(); List<Event> eventList = new ArrayList<>();
for (int i = 1; i <= count; i++) { for (int i = 1; i <= count; i++) {
eventList.add(EventBuilder.addUserEvent(group_id, "" + i)); eventList.add(addUserEvent(groupId, String.valueOf(i)));
} }
return eventList; return eventList;
} }
public static DeleteUserEvent deleteUserEvent(long group_id, String user_id) { public static DeleteUserEvent deleteUserEvent(long groupId, String userId) {
Faker faker = new Faker();
return new DeleteUserEvent( return new DeleteUserEvent(
group_id, groupId,
user_id userId
); );
} }
/** /**
* Erzeugt mehrere DeleteUserEvents, sodass eine Gruppe komplett geleert wird * Erzeugt mehrere DeleteUserEvents, sodass eine Gruppe komplett geleert wird.
* *
* @param group Gruppe welche geleert wird * @param group Gruppe welche geleert wird
* @return * @return Eventliste
*/ */
public static List<DeleteUserEvent> deleteUserEvents(Group group) { public static List<DeleteUserEvent> deleteUserEvents(Group group) {
List<DeleteUserEvent> eventList = new ArrayList<>(); List<DeleteUserEvent> eventList = new ArrayList<>();
for (User user : group.getMembers()) { for (User user : group.getMembers()) {
eventList.add(EventBuilder.deleteUserEvent(group.getId(), user.getUser_id())); eventList.add(deleteUserEvent(group.getId(), user.getId()));
} }
return eventList; return eventList;
} }
public static UpdateGroupDescriptionEvent updateGroupDescriptionEvent(long group_id) { public static UpdateGroupDescriptionEvent updateGroupDescriptionEvent(long groupId) {
Faker faker = new Faker(); Faker faker = new Faker();
return new UpdateGroupDescriptionEvent( return new UpdateGroupDescriptionEvent(
group_id, groupId,
faker.random().hex(), faker.random().hex(),
faker.leagueOfLegends().quote() faker.leagueOfLegends().quote()
); );
} }
public static UpdateGroupTitleEvent updateGroupTitleEvent(long group_id) { public static UpdateGroupTitleEvent updateGroupTitleEvent(long groupId) {
Faker faker = new Faker(); Faker faker = new Faker();
return new UpdateGroupTitleEvent( return new UpdateGroupTitleEvent(
group_id, groupId,
faker.random().hex(), faker.random().hex(),
faker.leagueOfLegends().champion() faker.leagueOfLegends().champion()
); );
} }
public static UpdateRoleEvent randomUpdateRoleEvent(long group_id, String user_id, Role role) { public static UpdateRoleEvent randomUpdateRoleEvent(long groupId, String userId, Role role) {
Faker faker = new Faker();
return new UpdateRoleEvent( return new UpdateRoleEvent(
group_id, groupId,
user_id, userId,
role role
); );
} }

View File

@ -1,18 +1,5 @@
package mops.gruppen2.domain; package mops.gruppen2.domain;
import mops.gruppen2.domain.Exceptions.UserAlreadyExistsException;
import mops.gruppen2.domain.Exceptions.UserNotFoundException;
import mops.gruppen2.domain.event.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
class GroupTest { class GroupTest {
/* /*
@BeforeEach @BeforeEach

View File

@ -1,25 +1,21 @@
package mops.gruppen2.domain.event; package mops.gruppen2.domain.event;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Exceptions.UserAlreadyExistsException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User; import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static mops.gruppen2.domain.Role.MEMBER;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertThrows;
class AddUserEventTest { class AddUserEventTest {
@Test @Test
public void userAllreadyExistExeption() throws EventException { void userAlreadyExistExeption() throws EventException {
Group group = new Group(); Group group = new Group();
User user = new User("user1", "Stein", "Speck", "@sdasd"); User user = new User("user1", "Stein", "Speck", "@sdasd");
group.getMembers().add(user); group.getMembers().add(user);
Event event1 = new AddUserEvent(4L, "user2", "Rock", "Roll", "and"); Event event1 = new AddUserEvent(4L, "user2", "Rock", "Roll", "and");
event1.apply(group); event1.apply(group);

View File

@ -1,34 +1,28 @@
package mops.gruppen2.domain.event; package mops.gruppen2.domain.event;
import mops.gruppen2.domain.Exceptions.EventException;
import mops.gruppen2.domain.Exceptions.UserAlreadyExistsException;
import mops.gruppen2.domain.Exceptions.UserNotFoundException;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User; import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.UserNotFoundException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static mops.gruppen2.domain.Role.MEMBER; import static mops.gruppen2.domain.Role.MEMBER;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertThrows;
class DeleteUserEventTest { class DeleteUserEventTest {
@Test @Test
void applyDeleteUser() throws EventException { void applyDeleteUser() throws EventException {
Group group = new Group(); Group group = new Group();
User user = new User("user1", "Stein", "Speck", "@sdasd"); User user = new User("user1", "Stein", "Speck", "@sdasd");
group.getMembers().add(user); group.getMembers().add(user);
group.getRoles().put("user1", MEMBER); group.getRoles().put("user1", MEMBER);
User user2 = new User("user2", "Rock", "Roll", "and"); User user2 = new User("user2", "Rock", "Roll", "and");
group.getMembers().add(user2); group.getMembers().add(user2);
group.getRoles().put("user2", MEMBER); group.getRoles().put("user2", MEMBER);
Event event = new DeleteUserEvent(1L, "user1"); Event event = new DeleteUserEvent(1L, "user1");
event.apply(group); event.apply(group);
assertThat(group.getMembers().size()).isEqualTo(1); assertThat(group.getMembers().size()).isEqualTo(1);
@ -39,18 +33,14 @@ class DeleteUserEventTest {
@Test @Test
void userDoesNotExistExeption() { void userDoesNotExistExeption() {
Group group = new Group(); Group group = new Group();
User user = new User("user1", "Stein", "Speck", "@sdasd"); User user = new User("user1", "Stein", "Speck", "@sdasd");
group.getMembers().add(user); group.getMembers().add(user);
group.getRoles().put("user1", MEMBER); group.getRoles().put("user1", MEMBER);
Event event = new DeleteUserEvent(17L, "user5"); Event event = new DeleteUserEvent(17L, "user5");
assertThrows(UserNotFoundException.class, () -> assertThrows(UserNotFoundException.class, () ->
event.apply(group) event.apply(group)
); );
assertThat(group.getMembers().size()).isEqualTo(1); assertThat(group.getMembers().size()).isEqualTo(1);
} }
} }

View File

@ -15,29 +15,33 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
class EventServiceTest { class EventServiceTest {
EventService eventService;
EventRepository eventRepositoryMock = mock(EventRepository.class); private EventRepository eventRepository;
private EventService eventService;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
eventService = new EventService(mock(SerializationService.class), eventRepositoryMock); eventRepository = mock(EventRepository.class);
eventService = new EventService(mock(JsonService.class), eventRepository);
} }
@Test @Test
void getMaxID() { void getMaxID() {
when(eventRepositoryMock.getHighesEvent_ID()).thenReturn(42L); when(eventRepository.getHighesEvent_ID()).thenReturn(42L);
assertEquals(eventService.getMaxEvent_id(), 42L); assertEquals(eventService.getMaxEvent_id(), 42L);
} }
@Test @Test
void checkGroupReturnNextValue() { void checkGroupReturnNextValue() {
when(eventRepositoryMock.getMaxGroupID()).thenReturn(2L); when(eventRepository.getMaxGroupID()).thenReturn(2L);
assertEquals(eventService.checkGroup(), 3L); assertEquals(eventService.checkGroup(), 3L);
} }
@ -45,7 +49,7 @@ class EventServiceTest {
@Test @Test
void checkGroupReturnOneIfDBIsEmpty() { void checkGroupReturnOneIfDBIsEmpty() {
List<EventDTO> eventDTOS = new ArrayList<>(); List<EventDTO> eventDTOS = new ArrayList<>();
when(eventRepositoryMock.findAll()).thenReturn(eventDTOS); when(eventRepository.findAll()).thenReturn(eventDTOS);
assertEquals(eventService.checkGroup(), 1); assertEquals(eventService.checkGroup(), 1);
} }
@ -54,14 +58,14 @@ class EventServiceTest {
void getDTOOffentlichTest() { void getDTOOffentlichTest() {
CreateGroupEvent createGroupEvent = new CreateGroupEvent(eventService.checkGroup(), "test", null, GroupType.LECTURE, Visibility.PUBLIC); CreateGroupEvent createGroupEvent = new CreateGroupEvent(eventService.checkGroup(), "test", null, GroupType.LECTURE, Visibility.PUBLIC);
EventDTO eventDTO = eventService.getDTO(createGroupEvent); EventDTO eventDTO = eventService.getDTO(createGroupEvent);
assertEquals(eventDTO.isVisibility(), true); assertTrue(eventDTO.isVisibility());
} }
@Test @Test
void getDTOPrivatTest() { void getDTOPrivatTest() {
AddUserEvent addUserEvent = new AddUserEvent(eventService.checkGroup(), "test", "franz", "mueller", "a@a"); AddUserEvent addUserEvent = new AddUserEvent(eventService.checkGroup(), "test", "franz", "mueller", "a@a");
EventDTO eventDTO = eventService.getDTO(addUserEvent); EventDTO eventDTO = eventService.getDTO(addUserEvent);
assertEquals(eventDTO.isVisibility(), false); assertFalse(eventDTO.isVisibility());
} }
} }

View File

@ -5,12 +5,9 @@ import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Visibility; import mops.gruppen2.domain.Visibility;
import mops.gruppen2.domain.event.AddUserEvent; import mops.gruppen2.domain.event.AddUserEvent;
import mops.gruppen2.domain.event.CreateGroupEvent; import mops.gruppen2.domain.event.CreateGroupEvent;
import mops.gruppen2.domain.event.DeleteGroupEvent;
import mops.gruppen2.domain.event.Event; import mops.gruppen2.domain.event.Event;
import mops.gruppen2.repository.EventRepository; import mops.gruppen2.repository.EventRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.ArrayList; import java.util.ArrayList;
@ -20,23 +17,23 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
class GroupServiceTest { class GroupServiceTest {
GroupService groupService;
EventRepository eventRepository; private GroupService groupService;
@BeforeEach @BeforeEach
public void setUp() { void setUp() {
groupService = new GroupService(mock(EventService.class), eventRepository); groupService = new GroupService(mock(EventService.class), mock(EventRepository.class));
} }
@Test @Test
void rightClassForSucsessfulGroup() throws Exception { void rightClassForSuccessfulGroup() throws Exception {
List<Event> eventList = new ArrayList<>(); List<Event> eventList = new ArrayList<>();
eventList.add(new CreateGroupEvent(1L, "Prof", null, GroupType.LECTURE, Visibility.PRIVATE)); eventList.add(new CreateGroupEvent(1L, "Prof", null, GroupType.LECTURE, Visibility.PRIVATE));
eventList.add(new AddUserEvent(1L, "Ulli", "Ulli", "Honnis", "FC@B.de")); eventList.add(new AddUserEvent(1L, "Ulli", "Ulli", "Honnis", "FC@B.de"));
assertThat(groupService.projectEventList(eventList).get(0)).isInstanceOf(Group.class); List<Group> groups = groupService.projectEventList(eventList);
assertThat(groups.get(0)).isInstanceOf(Group.class);
} }
} }