1

Merge pull request #1 from hhu-propra2/master

update
This commit is contained in:
Christoph
2020-04-05 22:10:50 +02:00
committed by GitHub
64 changed files with 1814 additions and 1213 deletions

View File

@ -4,13 +4,18 @@ on:
push:
branches:
- master
- dev
pull_request:
branches:
- master
- dev
paths-ignore:
- 'documentation/**'
- 'mysql/**'
- 'README.adoc'
- 'Dockerfile'
- 'docker-compose.yaml'
- '.gitignore'
jobs:
build:
runs-on: ubuntu-latest

View File

@ -1,10 +1,17 @@
= Gruppenbildung
Das System bietet eine zentrale Oberfläche zum erstellen und verwalten von Gruppen. Diese kann von anderen Systemen eingebunden werden, oder von Studierenden direkt aufgerufen werden. Außerdem wird eine API bereitgestellt für die Nutzung in anderen Systemen. Man kann Private und Öffentliche Gruppen erstellen. Private Gruppen kann man nur über einen Beitrittslink beitreten. Öffentliche Gruppen kann man ohne diesen beitreten. Man kann nach Öffentlichen Gruppen über eine Suchfunktion suchen.
Das System bietet eine zentrale Oberfläche zum erstellen und verwalten von Gruppen.
Diese kann von anderen Systemen eingebunden werden, oder von Studierenden direkt aufgerufen werden.
Außerdem wird eine API bereitgestellt für die Nutzung in anderen Systemen.
Man kann Private und Öffentliche Gruppen erstellen.
Private Gruppen kann man nur über einen Beitrittslink beitreten.
Öffentliche Gruppen kann man ohne diesen beitreten.
Man kann nach Öffentlichen Gruppen über eine Suchfunktion suchen.
=== Problem
Die meisten Teilsysteme von MOPS arbeiten mit Gruppierungen von Studenten: Materialien für Lerngruppen/Veranstaltungen, Gruppenportfolios, Gruppenabstimmungen etc. Jedes System müsste dementsprechend eine Gruppenverwaltung implementieren, was zeitaufwändig ist.
Die meisten Teilsysteme von MOPS arbeiten mit Gruppierungen von Studenten: Materialien für Lerngruppen/Veranstaltungen, Gruppenportfolios, Gruppenabstimmungen etc.
Jedes System müsste dementsprechend eine Gruppenverwaltung implementieren, was zeitaufwändig ist.
=== Ziele
@ -36,7 +43,8 @@ Die Gruppenverwaltung wird bieten:
Über *Mitglied* (interne Rolle):
* Mitglieder haben keine Rechte in der Gruppe. Sie können nur eigenständig aus der Gruppe austreten.
* Mitglieder haben keine Rechte in der Gruppe.
Sie können nur eigenständig aus der Gruppe austreten.
Für *Organisatoren* (keycloak Rolle):
@ -62,3 +70,6 @@ Für *Studenten* (keycloak Rolle) :
=== Verwendung
Die Anwendung kann mit `docker-compse up` im Wurzelverzeichnis gestartet werden, eine API-Doku befindet sich im Dokumentation-Ordner (das swagger-zip).
Der Import über CSV erfolgt nach dem Format `id,givenname,familyname,email`

View File

@ -1,90 +1,103 @@
import com.github.spotbugs.SpotBugsTask
plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
id 'com.github.spotbugs' version '3.0.0'
id 'checkstyle'
id 'com.github.spotbugs' version '3.0.0'
id 'checkstyle'
id 'pmd'
}
group = 'mops'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
spotbugs{
ignoreFailures = true
reportLevel = "high"
effort = "max"
toolVersion = '4.0.0-RC1'
spotbugs {
ignoreFailures = false
reportLevel = "high"
effort = "max"
toolVersion = '4.0.0-RC1'
}
tasks.withType(SpotBugsTask) {
reports {
xml.enabled = false
html.enabled = true
}
reports {
xml.enabled = false
html.enabled = true
}
}
pmd {
consoleOutput = true
ignoreFailures = true
toolVersion = "6.21.0"
rulePriority = 5
ruleSets = ["category/java/errorprone.xml",
"category/java/bestpractices.xml",
"category/java/security.xml",
"category/java/performance.xml",
"category/java/design.xml"]
}
checkstyle {
toolVersion = "8.28"
configFile = file("${rootDir}/config/checkstyle/checkstyle.xml")
ignoreFailures = true
toolVersion = "8.28"
configFile = file("${rootDir}/config/checkstyle/checkstyle.xml")
ignoreFailures = true
}
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
maven {
url = 'https://s3.cs.hhu.de/public/mops/'
metadataSources {
artifact()
}
}
mavenCentral()
maven {
url = 'https://s3.cs.hhu.de/public/mops/'
metadataSources {
artifact()
}
}
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.security.oauth:spring-security-oauth2:2.4.0.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.security.oauth:spring-security-oauth2:2.4.0.RELEASE'
implementation 'org.keycloak:keycloak-spring-boot-starter:9.0.0'
implementation 'org.keycloak.bom:keycloak-adapter-bom:9.0.0'
implementation 'mops:styleguide:2.1.0'
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'com.github.javafaker:javafaker:1.0.2'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.10.3'
implementation 'org.keycloak:keycloak-spring-boot-starter:9.0.0'
implementation 'org.keycloak.bom:keycloak-adapter-bom:9.0.0'
implementation 'mops:styleguide:2.1.0'
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'com.github.javafaker:javafaker:1.0.2'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.10.3'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.assertj:assertj-core:3.15.0'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'com.tngtech.archunit:archunit-junit5:0.13.1'
testImplementation 'org.assertj:assertj-core:3.15.0'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'com.tngtech.archunit:archunit-junit5:0.13.1'
}
test {
useJUnitPlatform()
useJUnitPlatform()
}

View File

@ -226,7 +226,7 @@
<property name="lineWrappingIndentation" value="8"/>
<property name="arrayInitIndent" value="4"/>
</module>
<module name="VariableDeclarationUsageDistance"/>
<!-- <module name="VariableDeclarationUsageDistance"/>-->
<module name="MethodParamPad">
<property name="tokens"
value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,

View File

@ -1,17 +0,0 @@
package mops.gruppen2.config;
import mops.gruppen2.service.EventService;
import mops.gruppen2.service.GroupService;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Gruppen2Config {
final GroupService groupService;
final EventService eventService;
public Gruppen2Config(GroupService groupService, EventService eventService) {
this.groupService = groupService;
this.eventService = eventService;
}
}

View File

@ -1,4 +1,4 @@
package mops.gruppen2.security;
package mops.gruppen2.config;
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
@ -42,4 +42,4 @@ public class KeycloakConfig {
return new OAuth2RestTemplate(resourceDetails);
}
}
}

View File

@ -1,4 +1,4 @@
package mops.gruppen2.security;
package mops.gruppen2.config;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents;
@ -33,8 +33,7 @@ class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider
= keycloakAuthenticationProvider();
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@ -42,28 +41,26 @@ class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(
new SessionRegistryImpl());
}
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public AccessToken getAccessToken() {
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder
.currentRequestAttributes()).getRequest();
return ((KeycloakPrincipal) request.getUserPrincipal())
.getKeycloakSecurityContext().getToken();
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/actuator/**")
.hasRole("monitoring")
.anyRequest()
.permitAll();
.antMatchers("/actuator/**")
.hasRole("monitoring")
.anyRequest()
.permitAll();
}
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public AccessToken getAccessToken() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.currentRequestAttributes()).getRequest();
return ((KeycloakPrincipal) request.getUserPrincipal())
.getKeycloakSecurityContext().getToken();
}
/**

View File

@ -22,8 +22,9 @@ import java.util.UUID;
import java.util.stream.Collectors;
/**
* Ein Beispiel für eine API mit Swagger.
* Api zum Datenabgleich mit Gruppenfindung.
*/
//TODO: API-Service?
@RestController
@RequestMapping("/gruppen2/api")
public class APIController {
@ -38,20 +39,20 @@ public class APIController {
this.userService = userService;
}
@GetMapping("/updateGroups/{status}")
@GetMapping("/updateGroups/{lastEventId}")
@Secured("ROLE_api_user")
@ApiOperation("Gibt alle Gruppen zurück in denen sich etwas geändert hat")
public GroupRequestWrapper updateGroup(@ApiParam("Letzter Status des Anfragestellers") @PathVariable Long status) throws EventException {
List<Event> events = eventService.getNewEvents(status);
@ApiOperation("Gibt alle Gruppen zurück, in denen sich etwas geändert hat")
public GroupRequestWrapper updateGroups(@ApiParam("Letzter Status des Anfragestellers") @PathVariable Long lastEventId) throws EventException {
List<Event> events = eventService.getNewEvents(lastEventId);
return APIFormatterService.wrap(eventService.getMaxEvent_id(), groupService.projectEventList(events));
return APIFormatterService.wrap(eventService.getMaxEventId(), groupService.projectEventList(events));
}
@GetMapping("/getGroupIdsOfUser/{teilnehmer}")
@GetMapping("/getGroupIdsOfUser/{userId}")
@Secured("ROLE_api_user")
@ApiOperation("Gibt alle Gruppen zurück in denen sich ein Teilnehmer befindet")
public List<String> getGroupsOfUser(@ApiParam("Teilnehmer dessen groupIds zurückgegeben werden sollen") @PathVariable String teilnehmer) {
return userService.getUserGroups(teilnehmer).stream()
@ApiOperation("Gibt alle Gruppen zurück, in denen sich ein Teilnehmer befindet")
public List<String> getGroupIdsOfUser(@ApiParam("Teilnehmer dessen groupIds zurückgegeben werden sollen") @PathVariable String userId) {
return userService.getUserGroups(userId).stream()
.map(group -> group.getId().toString())
.collect(Collectors.toList());
}
@ -59,10 +60,14 @@ public class APIController {
@GetMapping("/getGroup/{groupId}")
@Secured("ROLE_api_user")
@ApiOperation("Gibt die Gruppe mit der als Parameter mitgegebenden groupId zurück")
public Group getGroupFromId(@ApiParam("GruppenId der gefordeten Gruppe") @PathVariable String groupId) throws EventException {
public Group getGroupById(@ApiParam("GruppenId der gefordeten Gruppe") @PathVariable String groupId) throws EventException {
List<Event> eventList = eventService.getEventsOfGroup(UUID.fromString(groupId));
List<Group> groups = groupService.projectEventList(eventList);
if (groups.isEmpty()) {
return null;
}
return groups.get(0);
}

View File

@ -0,0 +1,120 @@
package mops.gruppen2.controller;
import mops.gruppen2.domain.Account;
import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.GroupService;
import mops.gruppen2.service.KeyCloakService;
import mops.gruppen2.service.ValidationService;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
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.multipart.MultipartFile;
import javax.annotation.security.RolesAllowed;
import java.util.UUID;
@Controller
@SessionScope
@RequestMapping("/gruppen2")
public class GroupCreationController {
private final GroupService groupService;
private final ControllerService controllerService;
private final ValidationService validationService;
public GroupCreationController(GroupService groupService, ControllerService controllerService, ValidationService validationService) {
this.groupService = groupService;
this.controllerService = controllerService;
this.validationService = validationService;
}
@RolesAllowed({"ROLE_orga", "ROLE_actuator"})
@GetMapping("/createOrga")
public String createGroupAsOrga(KeycloakAuthenticationToken token,
Model model) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
model.addAttribute("account", account);
model.addAttribute("lectures", groupService.getAllLecturesWithVisibilityPublic());
return "createOrga";
}
@RolesAllowed({"ROLE_orga", "ROLE_actuator"})
@PostMapping("/createOrga")
@CacheEvict(value = "groups", allEntries = true)
public String postCrateGroupAsOrga(KeycloakAuthenticationToken token,
@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam(value = "visibility", required = false) Boolean visibility,
@RequestParam(value = "lecture", required = false) Boolean lecture,
@RequestParam("userMaximum") Long userMaximum,
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
@RequestParam(value = "parent", required = false) String parent,
@RequestParam(value = "file", required = false) MultipartFile file) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
UUID parentUUID = controllerService.getUUID(parent);
validationService.checkFields(description, title, userMaximum, maxInfiniteUsers);
controllerService.createGroupAsOrga(account,
title,
description,
visibility,
lecture,
maxInfiniteUsers,
userMaximum,
parentUUID,
file);
return "redirect:/gruppen2";
}
@RolesAllowed("ROLE_studentin")
@GetMapping("/createStudent")
public String createGroupAsStudent(KeycloakAuthenticationToken token,
Model model) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
model.addAttribute("account", account);
model.addAttribute("lectures", groupService.getAllLecturesWithVisibilityPublic());
return "createStudent";
}
@RolesAllowed("ROLE_studentin")
@PostMapping("/createStudent")
@CacheEvict(value = "groups", allEntries = true)
public String postCreateGroupAsStudent(KeycloakAuthenticationToken token,
@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam("userMaximum") Long userMaximum,
@RequestParam(value = "visibility", required = false) Boolean visibility,
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
@RequestParam(value = "parent", required = false) String parent) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
UUID parentUUID = controllerService.getUUID(parent);
validationService.checkFields(description, title, userMaximum, maxInfiniteUsers);
controllerService.createGroup(account,
title,
description,
visibility,
null,
maxInfiniteUsers,
userMaximum,
parentUUID);
return "redirect:/gruppen2";
}
}

View File

@ -0,0 +1,281 @@
package mops.gruppen2.controller;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.InviteService;
import mops.gruppen2.service.KeyCloakService;
import mops.gruppen2.service.UserService;
import mops.gruppen2.service.ValidationService;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.multipart.MultipartFile;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
@Controller
@SessionScope
@RequestMapping("/gruppen2")
public class GroupDetailsController {
private final ControllerService controllerService;
private final UserService userService;
private final ValidationService validationService;
private final InviteService inviteService;
public GroupDetailsController(ControllerService controllerService, UserService userService, ValidationService validationService, InviteService inviteService) {
this.controllerService = controllerService;
this.userService = userService;
this.validationService = validationService;
this.inviteService = inviteService;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/details/{id}")
public String showGroupDetails(KeycloakAuthenticationToken token,
Model model,
HttpServletRequest request,
@PathVariable("id") String groupId) {
Group group = userService.getGroupById(UUID.fromString(groupId));
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
UUID parentId = group.getParent();
String actualURL = request.getRequestURL().toString();
String serverURL = actualURL.substring(0, actualURL.indexOf("gruppen2/"));
Group parent = controllerService.getParent(parentId);
validationService.throwIfGroupNotExisting(group.getTitle());
model.addAttribute("account", account);
if (!validationService.checkIfUserInGroup(group, user)) {
validationService.throwIfNoAccessToPrivate(group, user);
model.addAttribute("group", group);
model.addAttribute("parentId", parentId);
model.addAttribute("parent", parent);
return "detailsNoMember";
}
model.addAttribute("parentId", parentId);
model.addAttribute("parent", parent);
model.addAttribute("group", group);
model.addAttribute("roles", group.getRoles());
model.addAttribute("user", user);
model.addAttribute("admin", Role.ADMIN);
model.addAttribute("public", Visibility.PUBLIC);
model.addAttribute("private", Visibility.PRIVATE);
if (validationService.checkIfAdmin(group, user)) {
model.addAttribute("link", serverURL + "gruppen2/acceptinvite/" + inviteService.getLinkByGroupId(group.getId()));
}
return "detailsMember";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/details/changeMetadata/{id}")
public String changeMetadata(KeycloakAuthenticationToken token,
Model model,
@PathVariable("id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNoAdmin(group, user);
model.addAttribute("account", account);
model.addAttribute("title", group.getTitle());
model.addAttribute("description", group.getDescription());
model.addAttribute("admin", Role.ADMIN);
model.addAttribute("roles", group.getRoles());
model.addAttribute("groupId", group.getId());
model.addAttribute("user", user);
return "changeMetadata";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/changeMetadata")
@CacheEvict(value = "groups", allEntries = true)
public String postChangeMetadata(KeycloakAuthenticationToken token,
@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam("groupId") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNoAdmin(group, user);
validationService.checkFields(title, description);
controllerService.changeMetaData(account, group, title, description);
return "redirect:/gruppen2/details/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/details/members/{id}")
public String editMembers(KeycloakAuthenticationToken token,
Model model,
@PathVariable("id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
User user = new User(account);
validationService.throwIfNoAdmin(group, user);
model.addAttribute("account", account);
model.addAttribute("members", group.getMembers());
model.addAttribute("group", group);
model.addAttribute("admin", Role.ADMIN);
return "editMembers";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/members/changeRole")
@CacheEvict(value = "groups", allEntries = true)
public String changeRole(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId,
@RequestParam("user_id") String userId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
User principle = new User(account);
User user = new User(userId, "", "", "");
validationService.throwIfNoAdmin(group, principle);
//TODO: checkIfAdmin checkt nicht, dass die rolle geändert wurde. oder die rolle wird nicht geändert
controllerService.changeRole(account, user, group);
if (!validationService.checkIfAdmin(group, principle)) {
return "redirect:/gruppen2/details/" + groupId;
}
return "redirect:/gruppen2/details/members/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/members/changeMaximum")
@CacheEvict(value = "groups", allEntries = true)
public String changeMaxSize(KeycloakAuthenticationToken token,
@RequestParam("maximum") Long maximum,
@RequestParam("group_id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNewMaximumIsValid(maximum, group);
controllerService.updateMaxUser(account, UUID.fromString(groupId), maximum);
return "redirect:/gruppen2/details/members/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/members/deleteUser")
@CacheEvict(value = "groups", allEntries = true)
public String deleteUser(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId,
@RequestParam("user_id") String userId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User principle = new User(account);
User user = new User(userId, "", "", "");
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNoAdmin(group, principle);
controllerService.deleteUser(account, user, group);
if (!validationService.checkIfUserInGroup(group, principle)) {
return "redirect:/gruppen2";
}
return "redirect:/gruppen2/details/members/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/detailsBeitreten")
@CacheEvict(value = "groups", allEntries = true)
public String joinGroup(KeycloakAuthenticationToken token,
Model model,
@RequestParam("id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfUserAlreadyInGroup(group, user);
validationService.throwIfGroupFull(group);
controllerService.addUser(account, UUID.fromString(groupId));
model.addAttribute("account", account);
return "redirect:/gruppen2";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/leaveGroup")
@CacheEvict(value = "groups", allEntries = true)
public String leaveGroup(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
Group group = userService.getGroupById(UUID.fromString(groupId));
controllerService.deleteUser(account, user, group);
return "redirect:/gruppen2";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/deleteGroup")
@CacheEvict(value = "groups", allEntries = true)
public String deleteGroup(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNoAdmin(group, user);
controllerService.deleteGroupEvent(user.getId(), UUID.fromString(groupId));
return "redirect:/gruppen2";
}
@RolesAllowed({"ROLE_orga", "ROLE_actuator"})
@PostMapping("/details/members/addUsersFromCsv")
@CacheEvict(value = "groups", allEntries = true)
public String addUsersFromCsv(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId,
@RequestParam(value = "file", required = false) MultipartFile file) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
controllerService.addUsersFromCsv(account, file, groupId);
return "redirect:/gruppen2/details/members/" + groupId;
}
}

View File

@ -0,0 +1,56 @@
package mops.gruppen2.controller;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.PageNotFoundException;
import mops.gruppen2.service.KeyCloakService;
import mops.gruppen2.service.UserService;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.annotation.security.RolesAllowed;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@Controller
public class GruppenfindungController {
private final UserService userService;
public GruppenfindungController(UserService userService) {
this.userService = userService;
}
@GetMapping("")
public String redirect() {
return "redirect:/gruppen2";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/gruppen2")
public String index(KeycloakAuthenticationToken token,
Model model) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
model.addAttribute("account", account);
model.addAttribute("gruppen", userService.getUserGroups(user));
model.addAttribute("user", user);
return "index";
}
@GetMapping("/logout")
public String logout(HttpServletRequest request) throws ServletException {
request.logout();
return "redirect:/gruppen2/";
}
@GetMapping("/gruppen2/*")
public String defaultLink() throws PageNotFoundException {
throw new PageNotFoundException("\uD83D\uDE41");
}
}

View File

@ -1,28 +0,0 @@
package mops.gruppen2.controller;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.PageNotFoundException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
public class MopsController {
@GetMapping("")
public String redirect() {
return "redirect:/gruppen2/";
}
@GetMapping("/logout")
public String logout(HttpServletRequest request) throws Exception {
request.logout();
return "redirect:/gruppen2/";
}
@GetMapping("*")
public String defaultLink() throws EventException {
throw new PageNotFoundException("\uD83D\uDE41");
}
}

View File

@ -0,0 +1,123 @@
package mops.gruppen2.controller;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.InviteService;
import mops.gruppen2.service.KeyCloakService;
import mops.gruppen2.service.UserService;
import mops.gruppen2.service.ValidationService;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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 javax.annotation.security.RolesAllowed;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Controller
@SessionScope
@RequestMapping("/gruppen2")
public class SearchAndInviteController {
private final ValidationService validationService;
private final InviteService inviteService;
private final UserService userService;
private final ControllerService controllerService;
public SearchAndInviteController(ValidationService validationService, InviteService inviteService, UserService userService, ControllerService controllerService) {
this.validationService = validationService;
this.inviteService = inviteService;
this.userService = userService;
this.controllerService = controllerService;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/findGroup")
public String findGroup(KeycloakAuthenticationToken token,
Model model,
@RequestParam(value = "suchbegriff", required = false) String search) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
List<Group> groups = new ArrayList<>();
groups = validationService.checkSearch(search, groups, account);
model.addAttribute("account", account);
model.addAttribute("gruppen", groups);
model.addAttribute("inviteService", inviteService);
return "search";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/detailsSearch")
public String showGroupDetailsNoMember(KeycloakAuthenticationToken token,
Model model,
@RequestParam("id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
UUID parentId = group.getParent();
Group parent = controllerService.getParent(parentId);
User user = new User(account);
model.addAttribute("account", account);
if (validationService.checkIfUserInGroup(group, user)) {
return "redirect:/gruppen2/details/" + groupId;
}
model.addAttribute("group", group);
model.addAttribute("parentId", parentId);
model.addAttribute("parent", parent);
return "detailsNoMember";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/acceptinvite/{link}")
public String acceptInvite(KeycloakAuthenticationToken token,
Model model,
@PathVariable("link") String link) {
Group group = userService.getGroupById(inviteService.getGroupIdFromLink(link));
validationService.throwIfGroupNotExisting(group.getTitle());
model.addAttribute("account", KeyCloakService.createAccountFromPrincipal(token));
model.addAttribute("group", group);
if (group.getVisibility() == Visibility.PUBLIC) {
return "redirect:/gruppen2/details/" + group.getId();
}
return "joinprivate";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/acceptinvite")
@CacheEvict(value = "groups", allEntries = true)
public String postAcceptInvite(KeycloakAuthenticationToken token,
@RequestParam("id") String groupId) {
Account account = KeyCloakService.createAccountFromPrincipal(token);
User user = new User(account);
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfUserAlreadyInGroup(group, user);
validationService.throwIfGroupFull(group);
controllerService.addUser(account, UUID.fromString(groupId));
return "redirect:/gruppen2/details/" + groupId;
}
}

View File

@ -1,429 +0,0 @@
package mops.gruppen2.controller;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.PageNotFoundException;
import mops.gruppen2.security.Account;
import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.GroupService;
import mops.gruppen2.service.InviteService;
import mops.gruppen2.service.KeyCloakService;
import mops.gruppen2.service.UserService;
import mops.gruppen2.service.ValidationService;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.multipart.MultipartFile;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Controller
@SessionScope
@RequestMapping("/gruppen2")
public class WebController {
private final KeyCloakService keyCloakService;
private final GroupService groupService;
private final UserService userService;
private final ControllerService controllerService;
private final ValidationService validationService;
private final InviteService inviteService;
public WebController(KeyCloakService keyCloakService, GroupService groupService, UserService userService, ControllerService controllerService, ValidationService validationService, InviteService inviteService) {
this.keyCloakService = keyCloakService;
this.groupService = groupService;
this.userService = userService;
this.controllerService = controllerService;
this.validationService = validationService;
this.inviteService = inviteService;
}
/**
* Zeigt die index.html an.
*
* @param token toller token
* @param model tolles model
* @return index.html
*/
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("")
public String index(KeycloakAuthenticationToken token, Model model) {
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
model.addAttribute("gruppen", userService.getUserGroups(user));
model.addAttribute("user", user);
return "index";
}
@RolesAllowed({"ROLE_orga", "ROLE_actuator"})
@GetMapping("/createOrga")
public String createGroupAsOrga(KeycloakAuthenticationToken token, Model model) {
Account account = keyCloakService.createAccountFromPrincipal(token);
model.addAttribute("account", account);
model.addAttribute("lectures", groupService.getAllLecturesWithVisibilityPublic());
return "createOrga";
}
@RolesAllowed({"ROLE_orga", "ROLE_actuator"})
@PostMapping("/createOrga")
@CacheEvict(value = "groups", allEntries = true)
public String postCrateGroupAsOrga(KeycloakAuthenticationToken token,
@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam(value = "visibility", required = false) Boolean visibility,
@RequestParam(value = "lecture", required = false) Boolean lecture,
@RequestParam("userMaximum") Long userMaximum,
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
@RequestParam(value = "parent", required = false) String parent,
@RequestParam(value = "file", required = false) MultipartFile file) {
Account account = keyCloakService.createAccountFromPrincipal(token);
UUID parentUUID = controllerService.getUUID(parent);
validationService.checkFields(description, title, userMaximum, maxInfiniteUsers);
controllerService.createGroupAsOrga(account, title, description, visibility, lecture, maxInfiniteUsers, userMaximum, parentUUID, file);
return "redirect:/gruppen2/";
}
@RolesAllowed({"ROLE_studentin"})
@GetMapping("/createStudent")
public String createGroupAsStudent(KeycloakAuthenticationToken token, Model model) {
Account account = keyCloakService.createAccountFromPrincipal(token);
model.addAttribute("account", account);
model.addAttribute("lectures", groupService.getAllLecturesWithVisibilityPublic());
return "createStudent";
}
@RolesAllowed({"ROLE_studentin"})
@PostMapping("/createStudent")
@CacheEvict(value = "groups", allEntries = true)
public String postCreateGroupAsStudent(KeycloakAuthenticationToken token,
@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam(value = "visibility", required = false) Boolean visibility,
@RequestParam("userMaximum") Long userMaximum,
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
@RequestParam(value = "parent", required = false) String parent) {
Account account = keyCloakService.createAccountFromPrincipal(token);
UUID parentUUID = controllerService.getUUID(parent);
validationService.checkFields(description, title, userMaximum, maxInfiniteUsers);
controllerService.createGroup(account, title, description, visibility, null, maxInfiniteUsers, userMaximum, parentUUID);
return "redirect:/gruppen2/";
}
@RolesAllowed({"ROLE_orga", "ROLE_actuator"})
@PostMapping("/details/members/addUsersFromCsv")
@CacheEvict(value = "groups", allEntries = true)
public String addUsersFromCsv(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId,
@RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
Account account = keyCloakService.createAccountFromPrincipal(token);
controllerService.addUsersFromCsv(account, file, groupId);
return "redirect:/gruppen2/details/members/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/details/changeMetadata/{id}")
public String changeMetadata(KeycloakAuthenticationToken token, Model model, @PathVariable("id") String groupId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
Group group = userService.getGroupById(UUID.fromString(groupId));
UUID parentId = group.getParent();
Group parent = new Group();
validationService.throwIfNoAdmin(group, user);
model.addAttribute("account", account);
model.addAttribute("title", group.getTitle());
model.addAttribute("description", group.getDescription());
model.addAttribute("admin", Role.ADMIN);
model.addAttribute("roles", group.getRoles());
model.addAttribute("groupId", group.getId());
model.addAttribute("user", user);
return "changeMetadata";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/changeMetadata")
@CacheEvict(value = "groups", allEntries = true)
public String postChangeMetadata(KeycloakAuthenticationToken token,
@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam("groupId") String groupId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), "", "", "");
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNoAdmin(group, user);
validationService.checkFields(title, description);
controllerService.changeMetaData(account, group, title, description);
return "redirect:/gruppen2/details/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/findGroup")
public String findGroup(KeycloakAuthenticationToken token,
Model model,
@RequestParam(value = "suchbegriff", required = false) String search) {
Account account = keyCloakService.createAccountFromPrincipal(token);
List<Group> groups = new ArrayList<>();
groups = validationService.checkSearch(search, groups, account);
model.addAttribute("account", account);
model.addAttribute("gruppen", groups);
model.addAttribute("inviteService", inviteService);
return "search";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/details/{id}")
public String showGroupDetails(KeycloakAuthenticationToken token,
Model model,
HttpServletRequest request,
@PathVariable("id") String groupId) {
Group group = userService.getGroupById(UUID.fromString(groupId));
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
UUID parentId = group.getParent();
String actualURL = request.getRequestURL().toString();
String serverURL = actualURL.substring(0, actualURL.indexOf("gruppen2/"));
Group parent = controllerService.getParent(parentId);
validationService.throwIfGroupNotExisting(group.getTitle());
model.addAttribute("account", account);
if (!validationService.checkIfUserInGroup(group, user)) {
validationService.throwIfNoAccessToPrivate(group, user);
model.addAttribute("group", group);
model.addAttribute("parentId", parentId);
model.addAttribute("parent", parent);
return "detailsNoMember";
}
model.addAttribute("parentId", parentId);
model.addAttribute("parent", parent);
model.addAttribute("group", group);
model.addAttribute("roles", group.getRoles());
model.addAttribute("user", user);
model.addAttribute("admin", Role.ADMIN);
if (validationService.checkIfAdmin(group, user)) {
model.addAttribute("link", serverURL + "gruppen2/acceptinvite/" + inviteService.getLinkByGroupId(group.getId()));
}
return "detailsMember";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/detailsBeitreten")
@CacheEvict(value = "groups", allEntries = true)
public String joinGroup(KeycloakAuthenticationToken token,
Model model, @RequestParam("id") String groupId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfUserAlreadyInGroup(group, user);
validationService.throwIfGroupFull(group);
controllerService.addUser(account, UUID.fromString(groupId));
model.addAttribute("account", account);
return "redirect:/gruppen2/";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/detailsSearch")
public String showGroupDetailsNoMember(KeycloakAuthenticationToken token,
Model model,
@RequestParam("id") String groupId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
UUID parentId = group.getParent();
Group parent = controllerService.getParent(parentId);
User user = new User(account.getName(), "", "", "");
model.addAttribute("account", account);
if (validationService.checkIfUserInGroup(group, user)){
return "redirect:/gruppen2/details/" + groupId;
}
model.addAttribute("group", group);
model.addAttribute("parentId", parentId);
model.addAttribute("parent", parent);
return "detailsNoMember";
}
//TODO: Muss post-mapping sein
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/acceptinvite/{link}")
public String acceptInvite(KeycloakAuthenticationToken token,
Model model,
@PathVariable("link") String link) {
Group group = userService.getGroupById(inviteService.getGroupIdFromLink(link));
validationService.throwIfGroupNotExisting(group.getTitle());
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
model.addAttribute("group", group);
if (group.getVisibility() == Visibility.PUBLIC) {
return "redirect:/gruppen2/details/" + group.getId();
}
return "joinprivate";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/acceptinvite")
@CacheEvict(value = "groups", allEntries = true)
public String postAcceptInvite(KeycloakAuthenticationToken token,
@RequestParam("id") String groupId) {
Account acc = keyCloakService.createAccountFromPrincipal(token);
User user = new User(acc.getName(), acc.getGivenname(), acc.getFamilyname(), acc.getEmail());
if (!validationService.checkIfUserInGroup(userService.getGroupById(UUID.fromString(groupId)), user)) {
controllerService.addUser(keyCloakService.createAccountFromPrincipal(token), UUID.fromString(groupId));
}
return "redirect:/gruppen2/";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/leaveGroup")
@CacheEvict(value = "groups", allEntries = true)
public String pLeaveGroup(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), "", "", "");
Group group = userService.getGroupById(UUID.fromString(groupId));
controllerService.deleteUser(account, user, group);
return "redirect:/gruppen2/";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/deleteGroup")
@CacheEvict(value = "groups", allEntries = true)
public String pDeleteGroup(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNoAdmin(group, user);
controllerService.deleteGroupEvent(user.getId(), UUID.fromString(groupId));
return "redirect:/gruppen2/";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@GetMapping("/details/members/{id}")
public String editMembers(Model model,
KeycloakAuthenticationToken token,
@PathVariable("id") String groupId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
User user = new User(account.getName(), "", "", "");
validationService.throwIfNoAdmin(group, user);
model.addAttribute("account", account);
model.addAttribute("members", group.getMembers());
model.addAttribute("group", group);
model.addAttribute("admin", Role.ADMIN);
return "editMembers";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/members/changeRole")
@CacheEvict(value = "groups", allEntries = true)
public String changeRole(KeycloakAuthenticationToken token,
@RequestParam("group_id") String groupId,
@RequestParam("user_id") String userId) {
Account account = keyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
User principle = new User(account.getName(), "", "", "");
User user = new User(userId, "", "", "");
validationService.throwIfNoAdmin(group, principle);
controllerService.changeRole(account, user, group);
group = userService.getGroupById(UUID.fromString(groupId));
if (!validationService.checkIfAdmin(group, principle)) {
return "redirect:/gruppen2/details/" + groupId;
}
return "redirect:/gruppen2/details/members/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/members/changeMaximum")
@CacheEvict(value = "groups", allEntries = true)
public String changeMaxSize(@RequestParam("maximum") Long maximum,
@RequestParam("group_id") String groupId,
KeycloakAuthenticationToken token) {
Account account = keyCloakService.createAccountFromPrincipal(token);
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNewMaximumIsValid(maximum, group);
controllerService.updateMaxUser(account, UUID.fromString(groupId), maximum);
return "redirect:/gruppen2/details/members/" + groupId;
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/details/members/deleteUser")
@CacheEvict(value = "groups", allEntries = true)
public String deleteUser(@RequestParam("group_id") String groupId,
@RequestParam("user_id") String userId,
KeycloakAuthenticationToken token) {
Account account = keyCloakService.createAccountFromPrincipal(token);
User principle = new User(account.getName(), "", "", "");
User user = new User(userId, "", "", "");
Group group = userService.getGroupById(UUID.fromString(groupId));
validationService.throwIfNoAdmin(group, principle);
controllerService.deleteUser(account, user, group);
if (!validationService.checkIfUserInGroup(group, principle)) {
return "redirect:/gruppen2/";
}
return "redirect:/gruppen2/details/members/" + groupId;
}
@GetMapping("*")
public String defaultLink() throws EventException {
throw new PageNotFoundException("\uD83D\uDE41");
}
}

View File

@ -1,4 +1,4 @@
package mops.gruppen2.security;
package mops.gruppen2.domain;
import lombok.Value;

View File

@ -16,6 +16,7 @@ import java.util.UUID;
@Setter
public class Group {
//TODO: List to Hashmap
private final List<User> members;
private final Map<String, Role> roles;
private UUID id;
@ -27,8 +28,8 @@ public class Group {
private UUID parent;
public Group() {
this.members = new ArrayList<>();
this.roles = new HashMap<>();
members = new ArrayList<>();
roles = new HashMap<>();
}
}

View File

@ -1,5 +1,6 @@
package mops.gruppen2.domain;
public enum GroupType {
SIMPLE, LECTURE
SIMPLE,
LECTURE
}

View File

@ -1,5 +1,6 @@
package mops.gruppen2.domain;
public enum Role {
ADMIN, MEMBER
ADMIN,
MEMBER
}

View File

@ -15,4 +15,11 @@ public class User {
private String givenname;
private String familyname;
private String email;
public User(Account account) {
id = account.getName();
givenname = account.getGivenname();
familyname = account.getFamilyname();
email = account.getEmail();
}
}

View File

@ -1,5 +1,6 @@
package mops.gruppen2.domain;
public enum Visibility {
PUBLIC, PRIVATE
PUBLIC,
PRIVATE
}

View File

@ -1,6 +1,5 @@
package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group;
@ -16,7 +15,6 @@ import java.util.UUID;
* Fügt einen einzelnen Nutzer einer Gruppe hinzu.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor // For Jackson
public class AddUserEvent extends Event {
@ -33,14 +31,14 @@ public class AddUserEvent extends Event {
@Override
protected void applyEvent(Group group) throws EventException {
User user = new User(this.userId, this.givenname, this.familyname, this.email);
User user = new User(userId, givenname, familyname, email);
if (group.getMembers().contains(user)) {
throw new UserAlreadyExistsException(this.getClass().toString());
throw new UserAlreadyExistsException(getClass().toString());
}
if (group.getMembers().size() >= group.getUserMaximum()) {
throw new GroupFullException(this.getClass().toString());
throw new GroupFullException(getClass().toString());
}
group.getMembers().add(user);

View File

@ -1,6 +1,5 @@
package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group;
@ -10,7 +9,6 @@ import mops.gruppen2.domain.Visibility;
import java.util.UUID;
@Getter
@AllArgsConstructor
@NoArgsConstructor // For Jackson
public class CreateGroupEvent extends Event {
@ -21,18 +19,18 @@ public class CreateGroupEvent extends Event {
public CreateGroupEvent(UUID groupId, String userId, UUID parent, GroupType type, Visibility visibility, Long userMaximum) {
super(groupId, userId);
this.groupParent = parent;
this.groupType = type;
this.groupVisibility = visibility;
this.groupUserMaximum = userMaximum;
groupParent = parent;
groupType = type;
groupVisibility = visibility;
groupUserMaximum = userMaximum;
}
@Override
protected void applyEvent(Group group) {
group.setId(this.groupId);
group.setParent(this.groupParent);
group.setType(this.groupType);
group.setVisibility(this.groupVisibility);
group.setUserMaximum(this.groupUserMaximum);
group.setId(groupId);
group.setParent(groupParent);
group.setType(groupType);
group.setVisibility(groupVisibility);
group.setUserMaximum(groupUserMaximum);
}
}

View File

@ -23,5 +23,6 @@ public class DeleteGroupEvent extends Event {
group.setVisibility(null);
group.setType(null);
group.setParent(null);
group.setUserMaximum(0L);
}
}

View File

@ -39,13 +39,13 @@ public abstract class Event {
applyEvent(group);
}
protected abstract void applyEvent(Group group) throws EventException;
private void checkGroupIdMatch(UUID groupId) {
if (groupId == null || this.groupId.equals(groupId)) {
return;
}
throw new GroupIdMismatchException(this.getClass().toString());
throw new GroupIdMismatchException(getClass().toString());
}
protected abstract void applyEvent(Group group) throws EventException;
}

View File

@ -1,10 +1,9 @@
package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.NoValueException;
import mops.gruppen2.domain.exception.BadParameterException;
import java.util.UUID;
@ -12,7 +11,6 @@ import java.util.UUID;
* Ändert nur die Gruppenbeschreibung.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor // For Jackson
public class UpdateGroupDescriptionEvent extends Event {
@ -25,10 +23,10 @@ public class UpdateGroupDescriptionEvent extends Event {
@Override
protected void applyEvent(Group group) {
if (this.newGroupDescription.isEmpty()) {
throw new NoValueException(this.getClass().toString());
if (newGroupDescription.isEmpty()) {
throw new BadParameterException("Die Beschreibung ist leer.");
}
group.setDescription(this.newGroupDescription);
group.setDescription(newGroupDescription);
}
}

View File

@ -1,10 +1,9 @@
package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.NoValueException;
import mops.gruppen2.domain.exception.BadParameterException;
import java.util.UUID;
@ -12,7 +11,6 @@ import java.util.UUID;
* Ändert nur den Gruppentitel.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor // For Jackson
public class UpdateGroupTitleEvent extends Event {
@ -25,11 +23,11 @@ public class UpdateGroupTitleEvent extends Event {
@Override
protected void applyEvent(Group group) {
if (this.getNewGroupTitle().isEmpty()) {
throw new NoValueException(this.getClass().toString());
if (newGroupTitle.isEmpty()) {
throw new BadParameterException("Der Titel ist leer.");
}
group.setTitle(this.newGroupTitle);
group.setTitle(newGroupTitle);
}
}

View File

@ -1,6 +1,5 @@
package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group;
@ -13,7 +12,6 @@ import java.util.UUID;
* Aktualisiert die Gruppenrolle eines Teilnehmers.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor // For Jackson
public class UpdateRoleEvent extends Event {
@ -26,12 +24,12 @@ public class UpdateRoleEvent extends Event {
@Override
protected void applyEvent(Group group) throws UserNotFoundException {
if (group.getRoles().containsKey(this.userId)) {
group.getRoles().put(this.userId, this.newRole);
if (group.getRoles().containsKey(userId)) {
group.getRoles().put(userId, newRole);
return;
}
throw new UserNotFoundException(this.getClass().toString());
throw new UserNotFoundException(getClass().toString());
}
}

View File

@ -1,19 +1,18 @@
package mops.gruppen2.domain.event;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.BadParameterException;
import mops.gruppen2.domain.exception.EventException;
import java.util.UUID;
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class UpdateUserMaxEvent extends Event {
private Long userMaximum;
private Long userMaximum;
public UpdateUserMaxEvent(UUID groupId, String userId, Long userMaximum) {
super(groupId, userId);
@ -22,6 +21,10 @@ public class UpdateUserMaxEvent extends Event {
@Override
protected void applyEvent(Group group) throws EventException {
group.setUserMaximum(this.userMaximum);
if (userMaximum <= 0 || userMaximum < group.getMembers().size()) {
throw new BadParameterException("Usermaximum zu klein.");
}
group.setUserMaximum(userMaximum);
}
}

View File

@ -3,7 +3,7 @@ package mops.gruppen2.domain.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
public abstract class EventException extends ResponseStatusException {
public class EventException extends ResponseStatusException {
public EventException(HttpStatus status, String msg, String info) {
super(status, msg + " (" + info + ")");

View File

@ -1,10 +0,0 @@
package mops.gruppen2.domain.exception;
import org.springframework.http.HttpStatus;
public class NoValueException extends EventException {
public NoValueException(String info) {
super(HttpStatus.BAD_REQUEST, "Eine Information fehlt.", info);
}
}

View File

@ -3,6 +3,7 @@ package mops.gruppen2.domain.exception;
import org.springframework.http.HttpStatus;
public class WrongFileException extends EventException {
public WrongFileException(String info) {
super(HttpStatus.BAD_REQUEST, "Die entsprechende Datei ist keine valide CSV-Datei!", info);
}

View File

@ -29,7 +29,7 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
@Query("SELECT * FROM event WHERE event_type = :type")
List<EventDTO> findAllEventsByType(@Param("type") String type);
@Query("SELECT * FROM event WHERE event_type = :type AND user_id = :userId")
@Query("SELECT * FROM event WHERE event_type = :type AND user_id = :userId")
List<EventDTO> findEventsByTypeAndUserId(@Param("type") String type, @Param("userId") String userId);
@Query("SELECT COUNT(*) FROM event WHERE event_type = :type AND group_id = :groupId")

View File

@ -7,9 +7,11 @@ import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class APIFormatterService {
public final class APIFormatterService {
public static GroupRequestWrapper wrap(Long status, List<Group> groupList) {
private APIFormatterService() {}
public static GroupRequestWrapper wrap(long status, List<Group> groupList) {
return new GroupRequestWrapper(status, groupList);
}
}

View File

@ -1,5 +1,6 @@
package mops.gruppen2.service;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Role;
@ -14,18 +15,17 @@ import mops.gruppen2.domain.event.UpdateGroupTitleEvent;
import mops.gruppen2.domain.event.UpdateRoleEvent;
import mops.gruppen2.domain.event.UpdateUserMaxEvent;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.UserNotFoundException;
import mops.gruppen2.domain.exception.WrongFileException;
import mops.gruppen2.security.Account;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import static mops.gruppen2.domain.Role.ADMIN;
@ -34,30 +34,115 @@ import static mops.gruppen2.domain.Role.ADMIN;
@Service
public class ControllerService {
private static final Logger LOG = LoggerFactory.getLogger("controllerServiceLogger");
private final EventService eventService;
private final UserService userService;
private final ValidationService validationService;
private final InviteService inviteService;
private final Logger logger;
public ControllerService(EventService eventService, UserService userService, ValidationService validationService, InviteService inviteService) {
this.eventService = eventService;
this.userService = userService;
this.validationService = validationService;
this.inviteService = inviteService;
this.logger = Logger.getLogger("controllerServiceLogger");
}
private static User getVeteranMember(Account account, Group group) {
List<User> members = group.getMembers();
String newAdminId;
if (members.get(0).getId().equals(account.getName())) {
newAdminId = members.get(1).getId();
} else {
newAdminId = members.get(0).getId();
}
return new User(newAdminId, "", "", "");
}
/**
* Wie createGroup, nur das hier die Gruppe auch als Veranstaltung gesetzt werden kann und CSV Dateien mit Nutzern
* eingelesen werden können.
*
* @param account Der Nutzer der die Gruppe erstellt
* @param title Parameter für die neue Gruppe
* @param description Parameter für die neue Gruppe
* @param isVisibilityPrivate Parameter für die neue Gruppe
* @param isLecture Parameter für die neue Gruppe
* @param isMaximumInfinite Parameter für die neue Gruppe
* @param userMaximum Parameter für die neue Gruppe
* @param parent Parameter für die neue Gruppe
* @param file Parameter für die neue Gruppe
*/
public void createGroupAsOrga(Account account,
String title,
String description,
Boolean isVisibilityPrivate,
Boolean isLecture,
Boolean isMaximumInfinite,
Long userMaximum,
UUID parent,
MultipartFile file) {
userMaximum = checkInfiniteUsers(isMaximumInfinite, userMaximum);
List<User> newUsers = readCsvFile(file);
List<User> oldUsers = new ArrayList<>();
User user = new User(account);
oldUsers.add(user);
removeOldUsersFromNewUsers(oldUsers, newUsers);
userMaximum = adjustUserMaximum((long) newUsers.size(), 1L, userMaximum);
UUID groupId = createGroup(account,
title,
description,
isVisibilityPrivate,
isLecture,
isMaximumInfinite,
userMaximum, parent);
addUserList(newUsers, groupId);
}
/**
* Wenn die maximale Useranzahl unendlich ist, wird das Maximum auf 100000 gesetzt. Praktisch gibt es also Maximla 100000
* Nutzer pro Gruppe.
*
* @param isMaximumInfinite Gibt an ob es unendlich viele User geben soll
* @param userMaximum Das Maximum an Usern, falls es eins gibt
*
* @return Maximum an Usern
*/
private static Long checkInfiniteUsers(Boolean isMaximumInfinite, Long userMaximum) {
isMaximumInfinite = isMaximumInfinite != null;
if (isMaximumInfinite) {
userMaximum = 100_000L;
}
return userMaximum;
}
/**
* Erzeugt eine neue Gruppe, fügt den User, der die Gruppe erstellt hat, hinzu und setzt seine Rolle als Admin fest.
* Zudem wird der Gruppentitel und die Gruppenbeschreibung erzeugt, welche vorher der Methode übergeben wurden.
* Aus diesen Event Objekten wird eine Liste erzeugt, welche daraufhin mithilfe des EventServices gesichert wird.
* Aus diesen Event-Objekten wird eine Liste erzeugt, welche daraufhin mithilfe des EventServices gesichert wird.
*
* @param account Keycloak-Account
* @param title Gruppentitel
* @param description Gruppenbeschreibung
*/
public UUID createGroup(Account account, String title, String description, Boolean isVisibilityPrivate, Boolean isLecture, Boolean isMaximumInfinite, Long userMaximum, UUID parent) {
//TODO: remove booleans
public UUID createGroup(Account account,
String title,
String description,
Boolean isVisibilityPrivate,
Boolean isLecture,
Boolean isMaximumInfinite,
Long userMaximum,
UUID parent) {
userMaximum = checkInfiniteUsers(isMaximumInfinite, userMaximum);
Visibility groupVisibility = setGroupVisibility(isVisibilityPrivate);
@ -65,7 +150,12 @@ public class ControllerService {
GroupType groupType = setGroupType(isLecture);
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), parent, groupType, groupVisibility, userMaximum);
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId,
account.getName(),
parent,
groupType,
groupVisibility,
userMaximum);
eventService.saveEvent(createGroupEvent);
inviteService.createLink(groupId);
@ -80,38 +170,95 @@ public class ControllerService {
return groupId;
}
/**
* Wie createGroup, nur das hier die Gruppe auch als Veranstaltung gesetzt werden kann und CSV Dateien mit Nutzern
* eingelesen werden können.
* @param account Der Nutzer der die Gruppe erstellt
* @param title Parameter für die neue Gruppe
* @param description Parameter für die neue Gruppe
* @param isVisibilityPrivate Parameter für die neue Gruppe
* @param isLecture Parameter für die neue Gruppe
* @param isMaximumInfinite Parameter für die neue Gruppe
* @param userMaximum Parameter für die neue Gruppe
* @param parent Parameter für die neue Gruppe
* @param file Parameter für die neue Gruppe
*/
public void createGroupAsOrga(Account account, String title, String description, Boolean isVisibilityPrivate, Boolean isLecture, Boolean isMaximumInfinite, Long userMaximum, UUID parent, MultipartFile file) {
userMaximum = checkInfiniteUsers(isMaximumInfinite, userMaximum);
List<User> newUsers = readCsvFile(file);
List<User> oldUsers = new ArrayList<>();
User user = new User(account.getName(), "", "", "");
oldUsers.add(user);
removeOldUsersFromNewUsers(oldUsers, newUsers);
userMaximum = adjustUserMaximum((long) newUsers.size(), 1L, userMaximum);
UUID groupId = createGroup(account, title, description, isVisibilityPrivate, isLecture, isMaximumInfinite, userMaximum, parent);
addUserList(newUsers, groupId);
private static List<User> readCsvFile(MultipartFile file) throws EventException {
if (file == null) {
return new ArrayList<>();
}
if (!file.isEmpty()) {
try {
List<User> userList = CsvService.read(file.getInputStream());
return userList.stream().distinct().collect(Collectors.toList()); //filters duplicates from list
} catch (IOException ex) {
LOG.warn("File konnte nicht gelesen werden");
throw new WrongFileException(file.getOriginalFilename());
}
}
return new ArrayList<>();
}
public void addUsersFromCsv(Account account, MultipartFile file, String groupId) throws IOException{
private static void removeOldUsersFromNewUsers(List<User> oldUsers, List<User> newUsers) {
for (User oldUser : oldUsers) {
newUsers.remove(oldUser);
}
}
private static Long adjustUserMaximum(Long newUsers, Long oldUsers, Long maxUsers) {
if (oldUsers + newUsers > maxUsers) {
maxUsers = oldUsers + newUsers;
}
return maxUsers;
}
private void addUserList(List<User> newUsers, UUID groupId) {
for (User user : newUsers) {
Group group = userService.getGroupById(groupId);
if (group.getMembers().contains(user)) {
LOG.info("Benutzer {} ist bereits in Gruppe", user.getId());
} else {
AddUserEvent addUserEvent = new AddUserEvent(groupId, user.getId(), user.getGivenname(), user.getFamilyname(), user.getEmail());
eventService.saveEvent(addUserEvent);
}
}
}
private static Visibility setGroupVisibility(Boolean isVisibilityPrivate) {
isVisibilityPrivate = isVisibilityPrivate != null;
if (isVisibilityPrivate) {
return Visibility.PRIVATE;
} else {
return Visibility.PUBLIC;
}
}
private static GroupType setGroupType(Boolean isLecture) {
isLecture = isLecture != null;
if (isLecture) {
return GroupType.LECTURE;
} else {
return GroupType.SIMPLE;
}
}
public void addUser(Account account, UUID groupId) {
AddUserEvent addUserEvent = new AddUserEvent(groupId, account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
eventService.saveEvent(addUserEvent);
}
private void updateTitle(Account account, UUID groupId, String title) {
UpdateGroupTitleEvent updateGroupTitleEvent = new UpdateGroupTitleEvent(groupId, account.getName(), title);
eventService.saveEvent(updateGroupTitleEvent);
}
public void updateRole(User user, UUID groupId) throws EventException {
UpdateRoleEvent updateRoleEvent;
Group group = userService.getGroupById(groupId);
validationService.throwIfNotInGroup(group, user);
if (group.getRoles().get(user.getId()) == ADMIN) {
updateRoleEvent = new UpdateRoleEvent(group.getId(), user.getId(), Role.MEMBER);
} else {
updateRoleEvent = new UpdateRoleEvent(group.getId(), user.getId(), ADMIN);
}
eventService.saveEvent(updateRoleEvent);
}
private void updateDescription(Account account, UUID groupId, String description) {
UpdateGroupDescriptionEvent updateGroupDescriptionEvent = new UpdateGroupDescriptionEvent(groupId, account.getName(), description);
eventService.saveEvent(updateGroupDescriptionEvent);
}
public void addUsersFromCsv(Account account, MultipartFile file, String groupId) {
Group group = userService.getGroupById(UUID.fromString(groupId));
List<User> newUserList = readCsvFile(file);
@ -120,15 +267,24 @@ public class ControllerService {
UUID groupUUID = getUUID(groupId);
Long newUserMaximum = adjustUserMaximum((long) newUserList.size(), (long) group.getMembers().size(), group.getUserMaximum());
if (newUserMaximum > group.getUserMaximum()){
if (newUserMaximum > group.getUserMaximum()) {
updateMaxUser(account, groupUUID, newUserMaximum);
}
addUserList(newUserList, groupUUID);
}
public UUID getUUID(String id) {
return UUID.fromString(Objects.requireNonNullElse(id, "00000000-0000-0000-0000-000000000000"));
}
public void updateMaxUser(Account account, UUID groupId, Long userMaximum) {
UpdateUserMaxEvent updateUserMaxEvent = new UpdateUserMaxEvent(groupId, account.getName(), userMaximum);
eventService.saveEvent(updateUserMaxEvent);
}
public void changeMetaData(Account account, Group group, String title, String description) {
if (!title.equals(group.getTitle())){
if (!title.equals(group.getTitle())) {
updateTitle(account, group.getId(), title);
}
@ -145,114 +301,6 @@ public class ControllerService {
return parent;
}
private void removeOldUsersFromNewUsers(List<User> oldUsers, List<User> newUsers) {
for (User oldUser : oldUsers) {
newUsers.remove(oldUser);
}
}
/**
* Wenn die maximale Useranzahl unendlich ist, wird das Maximum auf 100000 gesetzt. Praktisch gibt es also Maximla 100000
* Nutzer pro Gruppe.
* @param isMaximumInfinite Gibt an ob es unendlich viele User geben soll
* @param userMaximum Das Maximum an Usern, falls es eins gibt
* @return Maximum an Usern
*/
private Long checkInfiniteUsers(Boolean isMaximumInfinite, Long userMaximum) {
isMaximumInfinite = isMaximumInfinite != null;
if (isMaximumInfinite) {
userMaximum = 100000L;
}
return userMaximum;
}
private Visibility setGroupVisibility(Boolean isVisibilityPrivate) {
isVisibilityPrivate = isVisibilityPrivate != null;
if (isVisibilityPrivate) {
return Visibility.PRIVATE;
} else {
return Visibility.PUBLIC;
}
}
private GroupType setGroupType(Boolean isLecture) {
isLecture = isLecture != null;
if (isLecture) {
return GroupType.LECTURE;
} else {
return GroupType.SIMPLE;
}
}
private List<User> readCsvFile(MultipartFile file) throws EventException{
if(file == null) return new ArrayList<>();
if (!file.isEmpty()) {
try {
List<User> userList = CsvService.read(file.getInputStream());
return userList.stream().distinct().collect(Collectors.toList()); //filters duplicates from list
} catch (IOException ex) {
logger.warning("File konnte nicht gelesen werden");
throw new WrongFileException(file.getOriginalFilename());
}
}
return new ArrayList<>();
}
private Long adjustUserMaximum(Long newUsers, Long oldUsers, Long maxUsers) {
if (oldUsers + newUsers > maxUsers) {
maxUsers = oldUsers + newUsers;
}
return maxUsers;
}
public void addUser(Account account, UUID groupId) {
AddUserEvent addUserEvent = new AddUserEvent(groupId, account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
eventService.saveEvent(addUserEvent);
}
public void addUserList(List<User> newUsers, UUID groupId) {
for (User user : newUsers) {
Group group = userService.getGroupById(groupId);
if (group.getMembers().contains(user)) {
logger.info("Benutzer " + user.getId() + " ist bereits in Gruppe");
} else {
AddUserEvent addUserEvent = new AddUserEvent(groupId, user.getId(), user.getGivenname(), user.getFamilyname(), user.getEmail());
eventService.saveEvent(addUserEvent);
}
}
}
public void updateTitle(Account account, UUID groupId, String title) {
UpdateGroupTitleEvent updateGroupTitleEvent = new UpdateGroupTitleEvent(groupId, account.getName(), title);
eventService.saveEvent(updateGroupTitleEvent);
}
public void updateDescription(Account account, UUID groupId, String description) {
UpdateGroupDescriptionEvent updateGroupDescriptionEvent = new UpdateGroupDescriptionEvent(groupId, account.getName(), description);
eventService.saveEvent(updateGroupDescriptionEvent);
}
public void updateMaxUser(Account account, UUID groupId, Long userMaximum) {
UpdateUserMaxEvent updateUserMaxEvent = new UpdateUserMaxEvent(groupId, account.getName(), userMaximum);
eventService.saveEvent(updateUserMaxEvent);
}
public void updateRole(User user, UUID groupId) throws EventException {
UpdateRoleEvent updateRoleEvent;
Group group = userService.getGroupById(groupId);
validationService.throwIfNotInGroup(group, user);
if (group.getRoles().get(user.getId()) == ADMIN) {
updateRoleEvent = new UpdateRoleEvent(group.getId(), user.getId(), Role.MEMBER);
} else {
updateRoleEvent = new UpdateRoleEvent(group.getId(), user.getId(), ADMIN);
}
eventService.saveEvent(updateRoleEvent);
}
public void deleteUser(Account account, User user, Group group) throws EventException {
changeRoleIfLastAdmin(account, group);
@ -265,6 +313,14 @@ public class ControllerService {
}
}
private static boolean idIsEmpty(UUID id) {
if (id == null) {
return true;
}
return "00000000-0000-0000-0000-000000000000".equals(id.toString());
}
private void deleteUserEvent(User user, UUID groupId) {
DeleteUserEvent deleteUserEvent = new DeleteUserEvent(groupId, user.getId());
eventService.saveEvent(deleteUserEvent);
@ -276,13 +332,6 @@ public class ControllerService {
eventService.saveEvent(deleteGroupEvent);
}
public void changeRoleIfLastAdmin(Account account, Group group) {
if (group.getMembers().size() <= 1) {
return;
}
promoteVeteranMember(account, group);
}
private void promoteVeteranMember(Account account, Group group) {
if (validationService.checkIfLastAdmin(account, group)) {
User newAdmin = getVeteranMember(account, group);
@ -290,6 +339,13 @@ public class ControllerService {
}
}
public void changeRoleIfLastAdmin(Account account, Group group) {
if (group.getMembers().size() <= 1) {
return;
}
promoteVeteranMember(account, group);
}
public void changeRole(Account account, User user, Group group) {
if (user.getId().equals(account.getName())) {
if (group.getMembers().size() <= 1) {
@ -300,31 +356,4 @@ public class ControllerService {
updateRole(user, group.getId());
}
private User getVeteranMember(Account account, Group group) {
List<User> members = group.getMembers();
String newAdminId;
if (members.get(0).getId().equals(account.getName())) {
newAdminId = members.get(1).getId();
} else {
newAdminId = members.get(0).getId();
}
return new User(newAdminId, "", "", "");
}
public UUID getUUID(String id) {
if (id == null) {
return UUID.fromString("00000000-0000-0000-0000-000000000000");
} else {
return UUID.fromString(id);
}
}
public boolean idIsEmpty(UUID id) {
if (id == null) {
return true;
}
return id.toString().equals("00000000-0000-0000-0000-000000000000");
}
}

View File

@ -11,9 +11,11 @@ import java.io.InputStream;
import java.util.List;
@Service
public class CsvService {
public final class CsvService {
public static List<User> read(InputStream stream) throws IOException {
private CsvService() {}
static List<User> read(InputStream stream) throws IOException {
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(User.class).withHeader().withColumnReordering(true);

View File

@ -4,6 +4,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import mops.gruppen2.domain.dto.EventDTO;
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 java.util.ArrayList;
@ -15,11 +17,10 @@ import java.util.stream.Collectors;
//TODO: Evtl aufsplitten in EventRepoService und EventService?
public class EventService {
private final JsonService jsonService;
private static final Logger LOG = LoggerFactory.getLogger(EventService.class);
private final EventRepository eventStore;
public EventService(JsonService jsonService, EventRepository eventStore) {
this.jsonService = jsonService;
public EventService(EventRepository eventStore) {
this.eventStore = eventStore;
}
@ -38,8 +39,40 @@ public class EventService {
}
}
/**
* Erzeugt aus einem Event Objekt ein EventDTO Objekt.
*
* @param event Event, welches in DTO übersetzt wird
*
* @return EventDTO (Neues DTO)
*/
public EventDTO getDTOFromEvent(Event event) {
String payload = "";
try {
payload = JsonService.serializeEvent(event);
} catch (JsonProcessingException e) {
LOG.error("Event ({}) konnte nicht serialisiert werden!", event.getClass());
}
return new EventDTO(null, event.getGroupId().toString(), event.getUserId(), getEventType(event), payload);
}
/**
* Gibt den Eventtyp als String wieder.
*
* @param event Event dessen Typ abgefragt werden soll
*
* @return Der Name des Typs des Events
*/
private static String getEventType(Event event) {
int lastDot = event.getClass().getName().lastIndexOf('.');
return event.getClass().getName().substring(lastDot + 1);
}
/**
* Speichert alle Events aus der übergebenen Liste in der DB.
*
* @param events Liste an Events die gespeichert werden soll
*/
@SafeVarargs
@ -51,40 +84,12 @@ public class EventService {
}
}
/**
* Erzeugt aus einem Event Objekt ein EventDTO Objekt.
* Ist die Gruppe öffentlich, dann wird die visibility auf true gesetzt.
*
* @param event Event, welches in DTO übersetzt wird
* @return EventDTO (Neues DTO)
*/
public EventDTO getDTOFromEvent(Event event) {
String payload = "";
try {
payload = jsonService.serializeEvent(event);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return new EventDTO(null, event.getGroupId().toString(), event.getUserId(), getEventType(event), payload);
}
/**
* Gibt den Eventtyp als String wieder.
* @param event Event dessen Typ abgefragt werden soll
* @return Der Name des Typs des Events
*/
private String getEventType(Event event) {
int lastDot = event.getClass().getName().lastIndexOf('.');
return event.getClass().getName().substring(lastDot + 1);
}
/**
* Findet alle Events welche ab dem neuen Status hinzugekommen sind.
* Sucht alle Events mit event_id > status
*
* @param status Die Id des zuletzt gespeicherten Events
*
* @return Liste von neueren Events
*/
public List<Event> getNewEvents(Long status) {
@ -98,28 +103,39 @@ public class EventService {
* Erzeugt aus einer Liste von eventDTOs eine Liste von Events.
*
* @param eventDTOS Liste von DTOs
*
* @return Liste von Events
*/
public List<Event> getEventsFromDTOs(Iterable<EventDTO> eventDTOS) {
List<Event> getEventsFromDTOs(Iterable<EventDTO> eventDTOS) {
List<Event> events = new ArrayList<>();
for (EventDTO eventDTO : eventDTOS) {
try {
events.add(jsonService.deserializeEvent(eventDTO.getEvent_payload()));
events.add(JsonService.deserializeEvent(eventDTO.getEvent_payload()));
} catch (JsonProcessingException e) {
e.printStackTrace();
LOG.error("Payload\n {}\n konnte nicht deserialisiert werden!", eventDTO.getEvent_payload());
}
}
return events;
}
public Long getMaxEvent_id() {
return eventStore.getHighesEventID();
public long getMaxEventId() {
long highestEvent = 0;
try {
highestEvent = eventStore.getHighesEventID();
} catch (NullPointerException e) {
LOG.debug("Eine maxId von 0 wurde zurückgegeben, da keine Events vorhanden sind.");
}
return highestEvent;
}
/**
* Gibt eine Liste mit allen Events zurück, die zu der Gruppe gehören.
*
* @param groupId Gruppe die betrachtet werden soll
*
* @return Liste aus Events
*/
public List<Event> getEventsOfGroup(UUID groupId) {
@ -128,24 +144,25 @@ public class EventService {
}
/**
* Gibt eine Liste aus GruppenIds zurück in denen sich der User befindet.
* Gibt eine Liste aus GruppenIds zurück, in denen sich der User befindet.
*
* @param userId Die Id des Users
*
* @return Liste aus GruppenIds
*/
public List<UUID> findGroupIdsByUser(String userId) {
return eventStore.findGroupIdsWhereUserId(userId, "AddUserEvent").stream()
.map(UUID::fromString)
.collect(Collectors.toList());
return eventStore.findGroupIdsWhereUserId(userId, "AddUserEvent").stream().map(UUID::fromString).collect(Collectors.toList());
}
/**
* Gibt true zurück, falls der User aktuell in der Gruppe ist, sonst false.
*
* @param groupId Id der Gruppe
* @param userId Id des zu überprüfenden Users
* @param userId Id des zu überprüfenden Users
*
* @return true or false
*/
public boolean userInGroup(UUID groupId, String userId) {
return eventStore.countEventsByGroupIdAndUserIdAndEventType(groupId.toString(), userId, "AddUserEvent")
> eventStore.countEventsByGroupIdAndUserIdAndEventType(groupId.toString(), userId, "DeleteUserEvent");
boolean userInGroup(UUID groupId, String userId) {
return eventStore.countEventsByGroupIdAndUserIdAndEventType(groupId.toString(), userId, "AddUserEvent") > eventStore.countEventsByGroupIdAndUserIdAndEventType(groupId.toString(), userId, "DeleteUserEvent");
}
}

View File

@ -1,5 +1,6 @@
package mops.gruppen2.service;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Visibility;
@ -7,7 +8,6 @@ import mops.gruppen2.domain.dto.EventDTO;
import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.repository.EventRepository;
import mops.gruppen2.security.Account;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@ -34,9 +34,10 @@ public class GroupService {
* Wandelt die Zeilen in Events um und gibt davon eine Liste zurück.
*
* @param groupIds Liste an IDs
*
* @return Liste an Events
*/
//TODO Das vielleicht in den EventRepoService?
//TODO: Das vielleicht in den EventRepoService?
public List<Event> getGroupEvents(List<UUID> groupIds) {
List<EventDTO> eventDTOS = new ArrayList<>();
for (UUID groupId : groupIds) {
@ -45,65 +46,6 @@ public class GroupService {
return eventService.getEventsFromDTOs(eventDTOS);
}
/**
* Erzeugt eine neue Map wo Gruppen aus den Events erzeugt und den Gruppen_ids zugeordnet werden.
* Die Gruppen werden als Liste zurückgegeben
*
* @param events Liste an Events
* @return Liste an Projizierten Gruppen
* @throws EventException Projektionsfehler
*/
public List<Group> projectEventList(List<Event> events) throws EventException {
Map<UUID, Group> groupMap = new HashMap<>();
events.parallelStream()
.forEachOrdered(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupId())));
return new ArrayList<>(groupMap.values());
}
/**
* Gibt die Gruppe mit der richtigen Id aus der übergebenen Map wieder, existiert diese nicht
* wird die Gruppe erstellt und der Map hizugefügt.
* @param groups Map aus GruppenIds und Gruppen
* @param groupId Die Id der Gruppe, die zurückgegeben werden soll
* @return Die gesuchte Gruppe
*/
private Group getOrCreateGroup(Map<UUID, Group> groups, UUID groupId) {
if (!groups.containsKey(groupId)) {
groups.put(groupId, new Group());
}
return groups.get(groupId);
}
/**
* Wird verwendet bei der Suche nach Gruppen: Titel, Beschreibung werden benötigt.
* Außerdem wird beachtet, ob der eingeloggte User bereits in entsprechenden Gruppen mitglied ist.
*
* @return Liste von projizierten Gruppen
* @throws EventException Projektionsfehler
*/
//TODO Rename
@Cacheable("groups")
public List<Group> getAllGroupWithVisibilityPublic(String userId) throws EventException {
List<Event> groupEvents = eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("CreateGroupEvent"));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("UpdateGroupDescriptionEvent")));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("UpdateGroupTitleEvent")));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("DeleteGroupEvent")));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("UpdateUserMaxEvent")));
List<Group> visibleGroups = projectEventList(groupEvents);
sortByGroupType(visibleGroups);
return visibleGroups.stream()
.filter(group -> group.getType() != null)
.filter(group -> !eventService.userInGroup(group.getId(), userId))
.filter(group -> group.getVisibility() == Visibility.PUBLIC)
.collect(Collectors.toList());
}
/**
* Wird verwendet beim Gruppe erstellen bei der Parent-Auswahl: nur Titel benötigt.
*
@ -119,18 +61,55 @@ public class GroupService {
List<Group> visibleGroups = projectEventList(createEvents);
return visibleGroups.stream()
.filter(group -> group.getType() == GroupType.LECTURE)
.filter(group -> group.getVisibility() == Visibility.PUBLIC)
.collect(Collectors.toList());
.filter(group -> group.getType() == GroupType.LECTURE)
.filter(group -> group.getVisibility() == Visibility.PUBLIC)
.collect(Collectors.toList());
}
/**
* Erzeugt eine neue Map wo Gruppen aus den Events erzeugt und den Gruppen_ids zugeordnet werden.
* Die Gruppen werden als Liste zurückgegeben.
*
* @param events Liste an Events
*
* @return Liste an Projizierten Gruppen
*
* @throws EventException Projektionsfehler
*/
public List<Group> projectEventList(List<Event> events) throws EventException {
Map<UUID, Group> groupMap = new HashMap<>();
events.parallelStream()
.forEachOrdered(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupId())));
return new ArrayList<>(groupMap.values());
}
/**
* Gibt die Gruppe mit der richtigen Id aus der übergebenen Map wieder, existiert diese nicht
* wird die Gruppe erstellt und der Map hizugefügt.
*
* @param groups Map aus GruppenIds und Gruppen
* @param groupId Die Id der Gruppe, die zurückgegeben werden soll
*
* @return Die gesuchte Gruppe
*/
private static Group getOrCreateGroup(Map<UUID, Group> groups, UUID groupId) {
if (!groups.containsKey(groupId)) {
groups.put(groupId, new Group());
}
return groups.get(groupId);
}
/**
* Filtert alle öffentliche Gruppen nach dem Suchbegriff und gibt diese als Liste von Gruppen zurück.
* Groß und Kleinschreibung wird nicht beachtet.
*
* @param search Der Suchstring
*
* @return Liste von projizierten Gruppen
*
* @throws EventException Projektionsfehler
*/
//Todo Rename
@ -140,19 +119,44 @@ public class GroupService {
return getAllGroupWithVisibilityPublic(account.getName());
}
return getAllGroupWithVisibilityPublic(account.getName())
.parallelStream()
.filter(group -> group.getTitle().toLowerCase().contains(search.toLowerCase())
|| group.getDescription().toLowerCase().contains(search.toLowerCase()))
.collect(Collectors.toList());
return getAllGroupWithVisibilityPublic(account.getName()).parallelStream().filter(group -> group.getTitle().toLowerCase().contains(search.toLowerCase()) || group.getDescription().toLowerCase().contains(search.toLowerCase())).collect(Collectors.toList());
}
/**
* Wird verwendet bei der Suche nach Gruppen: Titel, Beschreibung werden benötigt.
* Außerdem wird beachtet, ob der eingeloggte User bereits in entsprechenden Gruppen mitglied ist.
*
* @return Liste von projizierten Gruppen
*
* @throws EventException Projektionsfehler
*/
//TODO Rename
@Cacheable("groups")
public List<Group> getAllGroupWithVisibilityPublic(String userId) throws EventException {
List<Event> groupEvents = eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("CreateGroupEvent"));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("UpdateGroupDescriptionEvent")));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("UpdateGroupTitleEvent")));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("DeleteGroupEvent")));
groupEvents.addAll(eventService.getEventsFromDTOs(eventRepository.findAllEventsByType("UpdateUserMaxEvent")));
List<Group> visibleGroups = projectEventList(groupEvents);
sortByGroupType(visibleGroups);
return visibleGroups.stream()
.filter(group -> group.getType() != null)
.filter(group -> !eventService.userInGroup(group.getId(), userId))
.filter(group -> group.getVisibility() == Visibility.PUBLIC)
.collect(Collectors.toList());
}
/**
* Sortiert die übergebene Liste an Gruppen, sodass Veranstaltungen am Anfang der Liste sind.
*
* @param groups Die Liste von Gruppen die sortiert werden soll
*/
public void sortByGroupType(List<Group> groups) {
groups.sort((g1, g2) -> {
void sortByGroupType(List<Group> groups) {
groups.sort((Group g1, Group g2) -> {
if (g1.getType() == GroupType.LECTURE) {
return -1;
}

View File

@ -4,6 +4,8 @@ import mops.gruppen2.domain.dto.InviteLinkDTO;
import mops.gruppen2.domain.exception.InvalidInviteException;
import mops.gruppen2.domain.exception.NoInviteExistException;
import mops.gruppen2.repository.InviteRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.UUID;
@ -11,17 +13,18 @@ import java.util.UUID;
@Service
public class InviteService {
private static final Logger LOG = LoggerFactory.getLogger(InviteService.class);
private final InviteRepository inviteRepository;
public InviteService(InviteRepository inviteRepository) {
this.inviteRepository = inviteRepository;
}
public void createLink(UUID groupId) {
void createLink(UUID groupId) {
inviteRepository.save(new InviteLinkDTO(null, groupId.toString(), UUID.randomUUID().toString()));
}
public void destroyLink(UUID groupId) {
void destroyLink(UUID groupId) {
inviteRepository.deleteLinkOfGroup(groupId.toString());
}
@ -29,7 +32,7 @@ public class InviteService {
try {
return UUID.fromString(inviteRepository.findGroupIdByLink(link));
} catch (Exception e) {
e.printStackTrace();
LOG.error("Gruppe zu Link ({}) konnte nicht gefunden werden!", link);
}
throw new InvalidInviteException(link);
@ -39,7 +42,7 @@ public class InviteService {
try {
return inviteRepository.findLinkByGroupId(groupId.toString());
} catch (Exception e) {
e.printStackTrace();
LOG.error("Link zu Gruppe ({}) konnte nicht gefunden werden!", groupId);
}
throw new NoInviteExistException(groupId.toString());

View File

@ -9,17 +9,21 @@ import org.springframework.stereotype.Service;
* Übersetzt JSON-Event-Payloads zu Java-Event-Repräsentationen und zurück.
*/
@Service
public class JsonService {
public final class JsonService {
private JsonService() {}
/**
* Übersetzt mithilfe der Jackson-Library eine Java-Event-Repräsentation zu einem JSON-Event-Payload.
*
* @param event Java-Event-Repräsentation
*
* @return JSON-Event-Payload als String
*
* @throws JsonProcessingException Bei JSON Fehler
*/
public String serializeEvent(Event event) throws JsonProcessingException {
static String serializeEvent(Event event) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(event);
}
@ -28,10 +32,12 @@ public class JsonService {
* Übersetzt mithilfe der Jackson-Library einen JSON-Event-Payload zu einer Java-Event-Repräsentation.
*
* @param json JSON-Event-Payload als String
*
* @return Java-Event-Repräsentation
*
* @throws JsonProcessingException Bei JSON Fehler
*/
public Event deserializeEvent(String json) throws JsonProcessingException {
static Event deserializeEvent(String json) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(json, Event.class);
}

View File

@ -1,20 +1,23 @@
package mops.gruppen2.service;
import mops.gruppen2.security.Account;
import mops.gruppen2.domain.Account;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.stereotype.Service;
@Service
public class KeyCloakService {
public final class KeyCloakService {
private KeyCloakService() {}
/**
* Creates an Account.
*
* @param token Ein toller token
*
* @return Account with current userdata
*/
public Account createAccountFromPrincipal(KeycloakAuthenticationToken token) {
public static Account createAccountFromPrincipal(KeycloakAuthenticationToken token) {
KeycloakPrincipal principal = (KeycloakPrincipal) token.getPrincipal();
return new Account(
principal.getName(),

View File

@ -3,6 +3,4 @@ package mops.gruppen2.service;
import org.springframework.stereotype.Service;
@Service
public class SearchService {
}
public class SearchService {}

View File

@ -23,11 +23,19 @@ public class UserService {
this.eventService = eventService;
}
@Cacheable("groups")
public List<Group> getUserGroups(String userId) throws EventException {
return getUserGroups(new User(userId, "", "", ""));
}
/**
* Gibt eine Liste aus Gruppen zurück, in denen sich der übergebene User befindet.
*
* @param user Der User
*
* @return Liste aus Gruppen
*/
//TODO: Nur AddUserEvents + DeleteUserEvents betrachten
@Cacheable("groups")
public List<Group> getUserGroups(User user) {
List<UUID> groupIds = eventService.findGroupIdsByUser(user.getId());
@ -45,15 +53,13 @@ public class UserService {
return newGroups;
}
@Cacheable("groups")
public List<Group> getUserGroups(String userId) throws EventException {
return getUserGroups(new User(userId, null, null, null));
}
/**
* Gibt die Gruppe zurück, die zu der übergebenen Id passt.
*
* @param groupId Die Id der gesuchten Gruppe
*
* @return Die gesuchte Gruppe
*
* @throws EventException Wenn die Gruppe nicht gefunden wird
*/
public Group getGroupById(UUID groupId) throws EventException {

View File

@ -1,11 +1,17 @@
package mops.gruppen2.service;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.domain.exception.*;
import mops.gruppen2.security.Account;
import mops.gruppen2.domain.exception.BadParameterException;
import mops.gruppen2.domain.exception.GroupFullException;
import mops.gruppen2.domain.exception.GroupNotFoundException;
import mops.gruppen2.domain.exception.NoAccessException;
import mops.gruppen2.domain.exception.NoAdminAfterActionException;
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
import mops.gruppen2.domain.exception.UserNotFoundException;
import org.springframework.stereotype.Service;
import java.util.List;
@ -25,6 +31,7 @@ public class ValidationService {
this.groupService = groupService;
}
//TODO: make static or change return + assignment
public List<Group> checkSearch(String search, List<Group> groups, Account account) {
if (search != null) {
groups = groupService.findGroupWith(search, account);
@ -38,82 +45,80 @@ public class ValidationService {
}
}
public void throwIfNoAccessToPrivate(Group group, User user) {
if (!checkIfUserInGroup(group, user) && group.getVisibility() == Visibility.PRIVATE) {
throw new NoAccessException("");
}
}
public boolean checkIfUserInGroup(Group group, User user) {
return group.getMembers().contains(user);
}
public void throwIfUserAlreadyInGroup(Group group, User user) {
if (checkIfUserInGroup(group, user)) {
throw new UserAlreadyExistsException("@details");
}
}
public void throwIfNotInGroup(Group group, User user) {
void throwIfNotInGroup(Group group, User user) {
if (!checkIfUserInGroup(group, user)) {
throw new UserNotFoundException(this.getClass().toString());
throw new UserNotFoundException(getClass().toString());
}
}
public boolean checkIfUserInGroup(Group group, User user) {
return group.getMembers().contains(user);
}
public void throwIfGroupFull(Group group) {
if (group.getUserMaximum() < group.getMembers().size() + 1) {
throw new GroupFullException("Du kannst der Gruppe daher leider nicht beitreten.");
}
}
public boolean checkIfGroupEmpty(UUID groupId) {
boolean checkIfGroupEmpty(UUID groupId) {
return userService.getGroupById(groupId).getMembers().isEmpty();
}
public void throwIfNoAdmin(Group group, User user) {
throwIfNoAccessToPrivate(group, user);
if (group.getRoles().get(user.getId()) != Role.ADMIN) {
if (group.getRoles().get(user.getId()) != ADMIN) {
throw new NoAccessException("");
}
}
public void throwIfNoAccessToPrivate(Group group, User user) {
if (!checkIfUserInGroup(group, user) && group.getVisibility() == Visibility.PRIVATE) {
throw new NoAccessException("");
}
}
public boolean checkIfAdmin(Group group, User user) {
if (checkIfUserInGroup(group, user)) {
return group.getRoles().get(user.getId()) == Role.ADMIN;
return group.getRoles().get(user.getId()) == ADMIN;
}
return false;
}
public boolean checkIfLastAdmin(Account account, Group group) {
void throwIfLastAdmin(Account account, Group group) {
if (checkIfLastAdmin(account, group)) {
throw new NoAdminAfterActionException("Du bist letzter Admin!");
}
}
boolean checkIfLastAdmin(Account account, Group group) {
for (Map.Entry<String, Role> entry : group.getRoles().entrySet()) {
if (entry.getValue() == ADMIN) {
if (!(entry.getKey().equals(account.getName()))) {
return false;
}
if (entry.getValue() == ADMIN && !(entry.getKey().equals(account.getName()))) {
return false;
}
}
return true;
}
public void throwIfLastAdmin(Account account, Group group) {
if (checkIfLastAdmin(account, group)) {
throw new NoAdminAfterActionException("Du Otto bist letzter Admin!");
}
}
/**
* Überprüft ob alle Felder richtig gesetzt sind.
*
* @param description Die Beschreibung der Gruppe
* @param title Der Titel der Gruppe
* @param title Der Titel der Gruppe
* @param userMaximum Das user Limit der Gruppe
*/
public void checkFields(String title, String description, Long userMaximum, Boolean maxInfiniteUsers) {
if (description == null || description.trim().length() == 0) {
if (description == null || description.trim().isEmpty()) {
throw new BadParameterException("Die Beschreibung wurde nicht korrekt angegeben");
}
if (title == null || title.trim().length() == 0) {
if (title == null || title.trim().isEmpty()) {
throw new BadParameterException("Der Titel wurde nicht korrekt angegeben");
}
@ -121,19 +126,17 @@ public class ValidationService {
throw new BadParameterException("Teilnehmeranzahl wurde nicht korrekt angegeben");
}
if (userMaximum != null) {
if (userMaximum < 1 || userMaximum > 10000L) {
throw new BadParameterException("Teilnehmeranzahl wurde nicht korrekt angegeben");
}
if (userMaximum != null && (userMaximum < 1 || userMaximum > 10000L)) {
throw new BadParameterException("Teilnehmeranzahl wurde nicht korrekt angegeben");
}
}
public void checkFields(String title, String description) {
if (description == null || description.trim().length() == 0) {
if (description == null || description.trim().isEmpty()) {
throw new BadParameterException("Die Beschreibung wurde nicht korrekt angegeben");
}
if (title == null || title.trim().length() == 0) {
if (title == null || title.trim().isEmpty()) {
throw new BadParameterException("Der Titel wurde nicht korrekt angegeben");
}
}

View File

@ -1,6 +0,0 @@
insert into event values
(1,'8c15f614-fe04-4ac4-a2d7-d13e62ba8597','orga','CreateGroupEvent','{"type":"CreateGroupEvent","groupId":"8c15f614-fe04-4ac4-a2d7-d13e62ba8597","userId":"orga","groupVisibility":"PUBLIC","groupParent":null,"groupType":"SIMPLE","groupUserMaximum":2}'),
(2,'8c15f614-fe04-4ac4-a2d7-d13e62ba8597','orga','AddUserEvent','{"type":"AddUserEvent","groupId":"8c15f614-fe04-4ac4-a2d7-d13e62ba8597","userId":"orga","givenname":"orga","familyname":"orga","email":"blorga@orga.org"}'),
(3,'8c15f614-fe04-4ac4-a2d7-d13e62ba8597','orga','UpdateGroupTitleEvent','{"type":"UpdateGroupTitleEvent","groupId":"8c15f614-fe04-4ac4-a2d7-d13e62ba8597","userId":"orga","newGroupTitle":"sdsad"}'),
(4,'8c15f614-fe04-4ac4-a2d7-d13e62ba8597','orga','UpdateGroupDescriptionEvent','{"type":"UpdateGroupDescriptionEvent","groupId":"8c15f614-fe04-4ac4-a2d7-d13e62ba8597","userId":"orga","newGroupDescription":"sadsad"}'),
(5,'8c15f614-fe04-4ac4-a2d7-d13e62ba8597','orga','UpdateRoleEvent','{"type":"UpdateRoleEvent","groupId":"8c15f614-fe04-4ac4-a2d7-d13e62ba8597","userId":"orga","newRole":"ADMIN"}');

View File

@ -55,7 +55,8 @@
<div class="custom-control custom-checkbox">
<input class="custom-control-input" id="maxInfiniteUsers" th:name="maxInfiniteUsers"
type="checkbox">
<label class="custom-control-label" for="maxInfiniteUsers">Anzahl unbegrenzt</label>
<label class="custom-control-label" for="maxInfiniteUsers">Anzahl
unbegrenzt</label>
</div>
<div class="form-group mt-3" id="userMaximum">
<label for="userMaximum">Teilnehmeranzahl</label>
@ -66,7 +67,7 @@
<input class="custom-control-input" id="visibility" th:name="visibility"
type="checkbox">
<label class="custom-control-label" for="visibility">Private
Gruppe</label>
Gruppe</label>
</div>
<div class="custom-control custom-checkbox" id="lectureCheckbox">
<input class="custom-control-input" id="lecture" th:name="lecture"
@ -76,7 +77,8 @@
<div class="form-group" id="lectureParent">
<label for="parent"></label>
<select class="form-control" id="parent" name="parent">
<option disabled selected="true">--Bitte Veranstaltung auswählen--</option>
<option disabled selected="true">--Bitte Veranstaltung auswählen--
</option>
<option th:each="lecture : ${lectures}" th:name="parent" th:value="${lecture.getId()}" th:text="${lecture.getTitle()}">
</option>
</select>
@ -88,7 +90,8 @@
<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>
Mitgliedern
hochladen</label>
</div>
</div>
</div>

View File

@ -54,7 +54,8 @@
<div class="custom-control custom-checkbox">
<input class="custom-control-input" id="maxInfiniteUsers" th:name="maxInfiniteUsers"
type="checkbox">
<label class="custom-control-label" for="maxInfiniteUsers">Anzahl unbegrenzt</label>
<label class="custom-control-label" for="maxInfiniteUsers">Anzahl
unbegrenzt</label>
</div>
<div class="form-group mt-3" id="userMaximum">
<label for="userMaximum">Teilnehmeranzahl</label>
@ -65,12 +66,13 @@
<input class="custom-control-input" id="visibility" th:name="visibility"
type="checkbox">
<label class="custom-control-label" for="visibility">Private
Gruppe</label>
Gruppe</label>
</div>
<div class="form-group" id="lectureParent">
<label for="parent"></label>
<select class="form-control" id="parent" name="parent">
<option disabled selected="true">--Bitte Veranstaltung auswählen--</option>
<option disabled selected="true">--Bitte Veranstaltung auswählen--
</option>
<option th:each="lecture : ${lectures}" th:name="parent" th:value="${lecture.getId()}" th:text="${lecture.getTitle()}">
</option>
</select>

View File

@ -112,7 +112,9 @@
<div th:if="${group.getRoles().get(user.getId()) == admin}">
<form method="get"
th:action="@{/gruppen2/details/members/{id}(id=${group.getId()})}">
<button class="btn btn-secondary" style="background: slategrey; float: left">Mitglieder bearbeiten</button>
<button class="btn btn-secondary" style="background: slategrey; float: left">
Mitglieder bearbeiten
</button>
</form>
<br>
<br>
@ -122,7 +124,8 @@
<ul class="list-group-flush" style="background: slategrey"
th:each="member : ${group.getMembers()}">
<li class="list-group-item" style="background: aliceblue">
<span th:text="${member.getId()}"></span>
<span th:if='${group.getVisibility() == public}' th:text="${member.getId()}"></span>
<span th:if='${group.getVisibility() == private}' th:text="${#strings.abbreviate(member.getGivenname(), 15) + ' ' + member.getFamilyname().substring(0, 1) + '.'}"></span>
<span class="badge badge-success"
th:if='${group.getRoles().get(member.getId()) == admin}'>admin</span>
</li>

View File

@ -56,7 +56,8 @@
<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>
Mitgliedern
hochladen</label>
</div>
<div class="input-group-append">
<button class="btn btn-outline-secondary"
@ -99,7 +100,7 @@
</thead>
<tbody class="table-striped">
<tr th:each="member : ${group.getMembers()}">
<th th:text="${member.getId()}"></th>
<th th:text="${#strings.abbreviate(member.getGivenname(), 15) + ' ' + member.getFamilyname().substring(0, 1) + '.'}"></th>
<td>
<span th:if='${group.getRoles().get(member.getId()) != admin}'>Mitglied</span>
<span th:if='${group.getRoles().get(member.getId()) == admin}'>Admin</span>
@ -113,8 +114,7 @@
<input th:name="user_id" th:value="${member.getId()}"
type="hidden">
<button class="btn btn-warning btn-sm" type="submit"
style="margin: 5px">Rolle
ändern
style="margin: 5px;">Rolle ändern
</button>
</form>
<form method="post"
@ -134,7 +134,9 @@
</tbody>
</table>
<form method="get" th:action="@{/gruppen2/details/{id}(id=${group.getId()})}">
<button class="btn btn-primary" style="background: #52a1eb; border-style: none" type="submit">Fertig</button>
<button class="btn btn-primary" style="background: #52a1eb; border-style: none" type="submit">
Fertig
</button>
</form>
</div>
</div>

View File

@ -35,23 +35,24 @@
<h1>Gruppensuche</h1>
<div class="shadow-sm p-2"
style="border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
<form method="get" th:action="@{/gruppen2/findGroup}">
<div class="form-group">
<label for="suchleiste">Suchbegriff:</label>
<input class="form-control" id="suchleiste"
placeholder="z.B. Programmieren, Lerngruppe, ..."
th:name="suchbegriff" type="text">
</div>
<button class="btn btn-primary"
style="background: #52a1eb; border-style: none"
type="submit">Suchen
</button>
<button class="btn btn-primary"
style="background: deepskyblue; border-style: none"
type="submit">
<a style="color: white" href="/gruppen2/findGroup?suchbegriff=">Alle anzeigen</a>
</button>
</form>
<form method="get" th:action="@{/gruppen2/findGroup}">
<div class="form-group">
<label for="suchleiste">Suchbegriff:</label>
<input class="form-control" id="suchleiste"
placeholder="z.B. Programmieren, Lerngruppe, ..."
th:name="suchbegriff" type="text">
</div>
<button class="btn btn-primary"
style="background: #52a1eb; border-style: none"
type="submit">Suchen
</button>
<button class="btn btn-primary"
style="background: deepskyblue; border-style: none"
type="submit">
<a href="/gruppen2/findGroup?suchbegriff=" style="color: white">Alle
anzeigen</a>
</button>
</form>
</div>
<br>
<table class="table">

View File

@ -1,6 +1,7 @@
package mops.gruppen2;
import com.github.javafaker.Faker;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Role;
@ -13,7 +14,6 @@ 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 mops.gruppen2.security.Account;
import java.util.ArrayList;
import java.util.Collection;
@ -29,11 +29,11 @@ public class TestBuilder {
public static Account account(String name) {
return new Account(name,
"",
"",
"",
"",
null);
"",
"",
"",
"",
null);
}
public static Group apply(Group group, Event... events) {
@ -52,12 +52,14 @@ public class TestBuilder {
* Baut eine UUID.
*
* @param id Integer id
*
* @return UUID
*/
public static UUID uuidFromInt(int id) {
public static UUID uuidMock(int id) {
String idString = String.valueOf(Math.abs(id + 1));
return UUID.fromString("00000000-0000-0000-0000-"
+ "0".repeat(11 - String.valueOf(id).length())
+ id);
+ "0".repeat(11 - idString.length())
+ idString);
}
/**
@ -65,22 +67,23 @@ public class TestBuilder {
*
* @param count Gruppenanzahl
* @param membercount Mitgliederanzahl pro Gruppe
*
* @return Eventliste
*/
public static List<Event> completePublicGroups(int count, int membercount) {
return IntStream.range(0, count)
.parallel()
.mapToObj(i -> completePublicGroup(membercount))
.flatMap(Collection::stream)
.collect(Collectors.toList());
.parallel()
.mapToObj(i -> completePublicGroup(membercount))
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
public static List<Event> completePrivateGroups(int count, int membercount) {
return IntStream.range(0, count)
.parallel()
.mapToObj(i -> completePrivateGroup(membercount))
.flatMap(Collection::stream)
.collect(Collectors.toList());
.parallel()
.mapToObj(i -> completePrivateGroup(membercount))
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
public static List<Event> completePublicGroup(int membercount) {
@ -119,29 +122,30 @@ public class TestBuilder {
* Generiert mehrere CreateGroupEvents, 1 <= groupId <= count.
*
* @param count Anzahl der verschiedenen Gruppen
*
* @return Eventliste
*/
public static List<Event> createPublicGroupEvents(int count) {
return IntStream.range(0, count)
.parallel()
.mapToObj(i -> createPublicGroupEvent())
.collect(Collectors.toList());
.parallel()
.mapToObj(i -> createPublicGroupEvent())
.collect(Collectors.toList());
}
public static List<Event> createPrivateGroupEvents(int count) {
return IntStream.range(0, count)
.parallel()
.mapToObj(i -> createPublicGroupEvent())
.collect(Collectors.toList());
.parallel()
.mapToObj(i -> createPublicGroupEvent())
.collect(Collectors.toList());
}
public static List<Event> createMixedGroupEvents(int count) {
return IntStream.range(0, count)
.parallel()
.mapToObj(i -> faker.random().nextInt(0, 1) > 0.5
? createPublicGroupEvent()
: createPrivateGroupEvent())
.collect(Collectors.toList());
.parallel()
.mapToObj(i -> faker.random().nextInt(0, 1) > 0.5
? createPublicGroupEvent()
: createPrivateGroupEvent())
.collect(Collectors.toList());
}
public static Event createPrivateGroupEvent(UUID groupId) {
@ -191,13 +195,14 @@ public class TestBuilder {
*
* @param count Anzahl der Mitglieder
* @param groupId Gruppe, zu welcher geaddet wird
*
* @return Eventliste
*/
public static List<Event> addUserEvents(int count, UUID groupId) {
return IntStream.range(0, count)
.parallel()
.mapToObj(i -> addUserEvent(groupId, String.valueOf(i)))
.collect(Collectors.toList());
.parallel()
.mapToObj(i -> addUserEvent(groupId, String.valueOf(i)))
.collect(Collectors.toList());
}
public static Event addUserEvent(UUID groupId, String userId) {
@ -221,8 +226,8 @@ public class TestBuilder {
public static List<Event> deleteUserEvents(int count, List<Event> eventList) {
List<Event> removeEvents = new ArrayList<>();
List<Event> shuffle = eventList.parallelStream()
.filter(event -> event instanceof AddUserEvent)
.collect(Collectors.toList());
.filter(event -> event instanceof AddUserEvent)
.collect(Collectors.toList());
Collections.shuffle(shuffle);
@ -241,12 +246,13 @@ public class TestBuilder {
* Erzeugt mehrere DeleteUserEvents, sodass eine Gruppe komplett geleert wird.
*
* @param group Gruppe welche geleert wird
*
* @return Eventliste
*/
public static List<Event> deleteUserEvents(Group group) {
return group.getMembers().parallelStream()
.map(user -> deleteUserEvent(group.getId(), user.getId()))
.collect(Collectors.toList());
.map(user -> deleteUserEvent(group.getId(), user.getId()))
.collect(Collectors.toList());
}
public static Event deleteUserEvent(UUID groupId, String userId) {

View File

@ -14,18 +14,17 @@ public class LayeredArchitectureTest {
.layer("Domain").definedBy("..domain..")
.layer("Service").definedBy("..service")
.layer("Controller").definedBy("..controller..")
.layer("Repository").definedBy("..repository..")
.layer("Config").definedBy("..config..");
.layer("Repository").definedBy("..repository..");
@ArchTest
public static final ArchRule domainLayerShouldOnlyBeAccessedByServiceAndControllerLayer = layeredArchitecture
.whereLayer("Domain")
.mayOnlyBeAccessedByLayers("Service", "Controller", "Config");
.mayOnlyBeAccessedByLayers("Service", "Controller");
@ArchTest
public static final ArchRule serviceLayerShouldOnlyBeAccessedByControllerLayer = layeredArchitecture
.whereLayer("Service")
.mayOnlyBeAccessedByLayers("Controller", "Config");
.mayOnlyBeAccessedByLayers("Controller");
@ArchTest
public static final ArchRule repositoryLayerShouldOnlyBeAccessedByServiceLayer = layeredArchitecture

View File

@ -0,0 +1,167 @@
package mops.gruppen2.controller;
import mops.gruppen2.Gruppen2Application;
import mops.gruppen2.repository.EventRepository;
import mops.gruppen2.service.EventService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
import static mops.gruppen2.TestBuilder.addUserEvent;
import static mops.gruppen2.TestBuilder.createPrivateGroupEvent;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.deleteGroupEvent;
import static mops.gruppen2.TestBuilder.deleteUserEvent;
import static mops.gruppen2.TestBuilder.updateGroupTitleEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Gruppen2Application.class)
@Transactional
@Rollback
class APIControllerTest {
@Autowired
private EventRepository eventRepository;
@Autowired
private APIController apiController;
private EventService eventService;
@Autowired
private JdbcTemplate template;
@BeforeEach
void setUp() {
eventService = new EventService(eventRepository);
eventRepository.deleteAll();
//noinspection SqlResolve
template.execute("ALTER TABLE event ALTER COLUMN event_id RESTART WITH 1");
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void updateGroup_noGroup() {
assertThat(apiController.updateGroups(0L).getGroupList()).hasSize(0);
assertThat(apiController.updateGroups(4L).getGroupList()).hasSize(0);
assertThat(apiController.updateGroups(10L).getGroupList()).hasSize(0);
assertThat(apiController.updateGroups(0L).getStatus()).isEqualTo(0);
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void updateGroup_singleGroup() {
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
addUserEvent(uuidMock(0)),
addUserEvent(uuidMock(0)),
addUserEvent(uuidMock(0)),
addUserEvent(uuidMock(0)));
assertThat(apiController.updateGroups(0L).getGroupList()).hasSize(1);
assertThat(apiController.updateGroups(4L).getGroupList()).hasSize(1);
assertThat(apiController.updateGroups(10L).getGroupList()).hasSize(0);
assertThat(apiController.updateGroups(0L).getStatus()).isEqualTo(5);
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void updateGroup_multipleGroups() {
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
addUserEvent(uuidMock(0)),
addUserEvent(uuidMock(0)),
createPrivateGroupEvent(uuidMock(1)),
addUserEvent(uuidMock(1)),
addUserEvent(uuidMock(1)),
addUserEvent(uuidMock(1)));
assertThat(apiController.updateGroups(0L).getGroupList()).hasSize(2);
assertThat(apiController.updateGroups(4L).getGroupList()).hasSize(1);
assertThat(apiController.updateGroups(6L).getGroupList()).hasSize(1);
assertThat(apiController.updateGroups(7L).getGroupList()).hasSize(0);
assertThat(apiController.updateGroups(0L).getStatus()).isEqualTo(7);
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupsOfUser_noGroup() {
assertThat(apiController.getGroupIdsOfUser("A")).isEmpty();
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupsOfUser_singleGroup() {
eventService.saveAll(createPrivateGroupEvent(uuidMock(0)),
createPrivateGroupEvent(uuidMock(1)),
createPrivateGroupEvent(uuidMock(2)),
addUserEvent(uuidMock(0), "A"));
assertThat(apiController.getGroupIdsOfUser("A")).hasSize(1);
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupsOfUser_singleGroupDeletedUser() {
eventService.saveAll(createPrivateGroupEvent(uuidMock(0)),
addUserEvent(uuidMock(0), "A"),
deleteUserEvent(uuidMock(0), "A"));
assertThat(apiController.getGroupIdsOfUser("A")).isEmpty();
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupsOfUser_singleDeletedGroup() {
eventService.saveAll(createPrivateGroupEvent(uuidMock(0)),
addUserEvent(uuidMock(0), "A"),
deleteGroupEvent(uuidMock(0)));
assertThat(apiController.getGroupIdsOfUser("A")).isEmpty();
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupsOfUser_multipleGroups() {
eventService.saveAll(createPrivateGroupEvent(uuidMock(0)),
createPrivateGroupEvent(uuidMock(1)),
createPrivateGroupEvent(uuidMock(2)),
addUserEvent(uuidMock(0), "A"),
addUserEvent(uuidMock(0), "B"),
addUserEvent(uuidMock(1), "A"),
addUserEvent(uuidMock(2), "A"),
addUserEvent(uuidMock(2), "B"));
assertThat(apiController.getGroupIdsOfUser("A")).hasSize(3);
assertThat(apiController.getGroupIdsOfUser("B")).hasSize(2);
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupFromId_noGroup() {
assertThat(apiController.getGroupById(uuidMock(0).toString())).isEqualTo(null);
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupFromId_singleGroup() {
eventService.saveAll(createPrivateGroupEvent(uuidMock(0)));
assertThat(apiController.getGroupById(uuidMock(0).toString()).getId()).isEqualTo(uuidMock(0));
}
@Test
@WithMockUser(username = "api_user", roles = "api_user")
void getGroupFromId_deletedGroup() {
eventService.saveAll(createPrivateGroupEvent(uuidMock(0)),
updateGroupTitleEvent(uuidMock(0)),
deleteGroupEvent(uuidMock(0)));
assertThat(apiController.getGroupById(uuidMock(0).toString()).getTitle()).isEqualTo(null);
}
}

View File

@ -1,35 +1,57 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.GroupFullException;
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static mops.gruppen2.TestBuilder.addUserEvent;
import static mops.gruppen2.TestBuilder.apply;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class AddUserEventTest {
@Test
void userAlreadyExistExeption() throws EventException {
Group group = new Group();
User user = new User("user1", "Stein", "Speck", "@sdasd");
group.getMembers().add(user);
group.setUserMaximum(10L);
UUID id = UUID.randomUUID();
Event event1 = new AddUserEvent(id, "user2", "Rock", "Roll", "and");
event1.apply(group);
void applyEvent() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event addEvent = new AddUserEvent(uuidMock(0), "A", "Thomas", "Tom", "tho@mail.de");
Event event2 = new AddUserEvent(id, "user1", "Rock", "Roll", "and");
Group group = apply(createEvent, addEvent);
assertThrows(UserAlreadyExistsException.class, () ->
event2.apply(group)
);
assertThat(group.getMembers().size()).isEqualTo(2);
assertThat(group.getMembers()).hasSize(1);
assertThat(group.getMembers().get(0).getGivenname()).isEqualTo("Thomas");
assertThat(group.getMembers().get(0).getFamilyname()).isEqualTo("Tom");
assertThat(group.getMembers().get(0).getEmail()).isEqualTo("tho@mail.de");
}
@Test
void applyEvent_userAlreadyExists() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event addEventA = addUserEvent(uuidMock(0), "A");
Event addEventB = addUserEvent(uuidMock(0), "B");
Event addEventC = addUserEvent(uuidMock(0), "A");
Group group = apply(createEvent, addEventA, addEventB);
assertThrows(UserAlreadyExistsException.class, () -> addEventA.apply(group));
assertThrows(UserAlreadyExistsException.class, () -> addEventC.apply(group));
assertThat(group.getMembers()).hasSize(2);
}
@Test
void applyEvent_groupFull() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event maxSizeEvent = new UpdateUserMaxEvent(uuidMock(0), "A", 2L);
Event addEventA = addUserEvent(uuidMock(0), "A");
Event addEventB = addUserEvent(uuidMock(0), "B");
Event addEventC = addUserEvent(uuidMock(0), "C");
Group group = apply(createEvent, maxSizeEvent, addEventA, addEventB);
assertThrows(GroupFullException.class, () -> addEventC.apply(group));
assertThat(group.getMembers()).hasSize(2);
}
}

View File

@ -0,0 +1,32 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.TestBuilder;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Visibility;
import org.junit.jupiter.api.Test;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
class CreateGroupEventTest {
@Test
void applyEvent() {
Event createEvent = new CreateGroupEvent(uuidMock(0),
"A",
uuidMock(1),
GroupType.SIMPLE,
Visibility.PUBLIC,
100L);
Group group = TestBuilder.apply(createEvent);
assertThat(group.getMembers()).hasSize(0);
assertThat(group.getType()).isEqualTo(GroupType.SIMPLE);
assertThat(group.getVisibility()).isEqualTo(Visibility.PUBLIC);
assertThat(group.getUserMaximum()).isEqualTo(100);
assertThat(group.getId()).isEqualTo(uuidMock(0));
assertThat(group.getParent()).isEqualTo(uuidMock(1));
}
}

View File

@ -0,0 +1,33 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.TestBuilder;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Visibility;
import org.junit.jupiter.api.Test;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
class DeleteGroupEventTest {
@Test
void applyEvent() {
Event createEvent = new CreateGroupEvent(uuidMock(0),
"A",
uuidMock(1),
GroupType.SIMPLE,
Visibility.PUBLIC,
100L);
Event deleteEvent = new DeleteGroupEvent(uuidMock(0), "A");
Group group = TestBuilder.apply(createEvent, deleteEvent);
assertThat(group.getMembers()).isEmpty();
assertThat(group.getType()).isEqualTo(null);
assertThat(group.getVisibility()).isEqualTo(null);
assertThat(group.getUserMaximum()).isEqualTo(0);
assertThat(group.getId()).isEqualTo(uuidMock(0));
assertThat(group.getParent()).isEqualTo(null);
}
}

View File

@ -1,48 +1,38 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.TestBuilder;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.UserNotFoundException;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static mops.gruppen2.domain.Role.MEMBER;
import static mops.gruppen2.TestBuilder.addUserEvent;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class DeleteUserEventTest {
@Test
void applyDeleteUser() throws EventException {
Group group = new Group();
User user = new User("user1", "Stein", "Speck", "@sdasd");
group.getMembers().add(user);
group.getRoles().put("user1", MEMBER);
User user2 = new User("user2", "Rock", "Roll", "and");
group.getMembers().add(user2);
group.getRoles().put("user2", MEMBER);
void applyEvent() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event addEvent = addUserEvent(uuidMock(0), "A");
Event deleteEvent = new DeleteUserEvent(uuidMock(0), "A");
Event event = new DeleteUserEvent(UUID.randomUUID(), "user1");
event.apply(group);
assertThat(group.getMembers().size()).isEqualTo(1);
assertThat(group.getRoles().size()).isEqualTo(1);
Group group = TestBuilder.apply(createEvent, addEvent, deleteEvent);
assertThat(group.getMembers()).hasSize(0);
}
@Test
void userDoesNotExistExeption() {
Group group = new Group();
User user = new User("user1", "Stein", "Speck", "@sdasd");
group.getMembers().add(user);
group.getRoles().put("user1", MEMBER);
void applyEvent_userNotFound() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event addEvent = addUserEvent(uuidMock(0), "A");
Event deleteEvent = new DeleteUserEvent(uuidMock(0), "B");
Event event = new DeleteUserEvent(UUID.randomUUID(), "user5");
assertThrows(UserNotFoundException.class, () ->
event.apply(group)
);
assertThat(group.getMembers().size()).isEqualTo(1);
Group group = TestBuilder.apply(createEvent, addEvent);
assertThrows(UserNotFoundException.class, () -> deleteEvent.apply(group));
assertThat(group.getMembers()).hasSize(1);
}
}

View File

@ -0,0 +1,24 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.TestBuilder;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.GroupIdMismatchException;
import org.junit.jupiter.api.Test;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.junit.jupiter.api.Assertions.assertThrows;
class EventTest {
@Test
void apply() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event addEvent = TestBuilder.addUserEvent(uuidMock(1));
Group group = TestBuilder.apply(createEvent);
assertThrows(GroupIdMismatchException.class, () -> addEvent.apply(group));
}
}

View File

@ -0,0 +1,36 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.TestBuilder;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.BadParameterException;
import org.junit.jupiter.api.Test;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class UpdateGroupDescriptionEventTest {
@Test
void applyEvent() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEvent = new UpdateGroupDescriptionEvent(uuidMock(0), "A", "desc.");
Group group = TestBuilder.apply(createEvent, updateEvent);
assertThat(group.getDescription()).isEqualTo("desc.");
}
@Test
void applyEvent_badDescription() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEventA = new UpdateGroupDescriptionEvent(uuidMock(0), "A", "");
Event updateEventB = new UpdateGroupDescriptionEvent(uuidMock(0), "A", " ");
Group group = TestBuilder.apply(createEvent);
assertThrows(BadParameterException.class, () -> updateEventA.apply(group));
assertThrows(BadParameterException.class, () -> updateEventB.apply(group));
}
}

View File

@ -0,0 +1,36 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.TestBuilder;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.BadParameterException;
import org.junit.jupiter.api.Test;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class UpdateGroupTitleEventTest {
@Test
void applyEvent() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEvent = new UpdateGroupTitleEvent(uuidMock(0), "A", "title.");
Group group = TestBuilder.apply(createEvent, updateEvent);
assertThat(group.getTitle()).isEqualTo("title.");
}
@Test
void applyEvent_badDescription() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEventA = new UpdateGroupTitleEvent(uuidMock(0), "A", "");
Event updateEventB = new UpdateGroupTitleEvent(uuidMock(0), "A", " ");
Group group = TestBuilder.apply(createEvent);
assertThrows(BadParameterException.class, () -> updateEventA.apply(group));
assertThrows(BadParameterException.class, () -> updateEventB.apply(group));
}
}

View File

@ -0,0 +1,39 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.exception.UserNotFoundException;
import org.junit.jupiter.api.Test;
import static mops.gruppen2.TestBuilder.addUserEvent;
import static mops.gruppen2.TestBuilder.apply;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class UpdateRoleEventTest {
@Test
void applyEvent() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event addEvent = addUserEvent(uuidMock(0), "A");
Event updateEvent = new UpdateRoleEvent(uuidMock(0), "A", Role.ADMIN);
Group group = apply(createEvent, addEvent, updateEvent);
assertThat(group.getRoles().get("A")).isEqualTo(Role.ADMIN);
}
@Test
void applyEvent_userNotFound() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event addEvent = addUserEvent(uuidMock(0), "A");
Event updateEvent = new UpdateRoleEvent(uuidMock(0), "B", Role.ADMIN);
Group group = apply(createEvent, addEvent);
assertThrows(UserNotFoundException.class, () -> updateEvent.apply(group));
assertThat(group.getRoles().get("A")).isEqualTo(Role.MEMBER);
}
}

View File

@ -0,0 +1,49 @@
package mops.gruppen2.domain.event;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.exception.BadParameterException;
import org.junit.jupiter.api.Test;
import static mops.gruppen2.TestBuilder.addUserEvent;
import static mops.gruppen2.TestBuilder.apply;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class UpdateUserMaxEventTest {
@Test
void applyEvent() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEvent = new UpdateUserMaxEvent(uuidMock(0), "A", 5L);
Group group = apply(createEvent, updateEvent);
assertThat(group.getUserMaximum()).isEqualTo(5);
}
@Test
void applyEvent_badParameter_negative() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEvent = new UpdateUserMaxEvent(uuidMock(0), "A", -5L);
Group group = apply(createEvent);
assertThrows(BadParameterException.class, () -> updateEvent.apply(group));
}
@Test
void applyEvent_badParameter_tooSmall() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEventA = new UpdateUserMaxEvent(uuidMock(0), "A", 5L);
Event addEventA = addUserEvent(uuidMock(0));
Event addEventB = addUserEvent(uuidMock(0));
Event addEventC = addUserEvent(uuidMock(0));
Event updateEventB = new UpdateUserMaxEvent(uuidMock(0), "A", 2L);
Group group = apply(createEvent, updateEventA, addEventA, addEventB, addEventC);
assertThrows(BadParameterException.class, () -> updateEventB.apply(group));
}
}

View File

@ -1,14 +1,14 @@
package mops.gruppen2.service;
import mops.gruppen2.Gruppen2Application;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.domain.exception.UserNotFoundException;
import mops.gruppen2.repository.EventRepository;
import mops.gruppen2.security.Account;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -33,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
@Transactional
@Rollback
class ControllerServiceTest {
Account account;
Account account2;
Account account3;
@ -44,13 +45,11 @@ class ControllerServiceTest {
EventRepository eventRepository;
GroupService groupService;
@Autowired
JsonService jsonService;
@Autowired
InviteService inviteService;
@BeforeEach
void setUp() {
eventService = new EventService(jsonService, eventRepository);
eventService = new EventService(eventRepository);
groupService = new GroupService(eventService, eventRepository);
userService = new UserService(groupService, eventService);
validationService = new ValidationService(userService, groupService);
@ -136,7 +135,7 @@ class ControllerServiceTest {
void createPublicGroupWithParentAndUnlimitedNumberTest() throws IOException {
controllerService.createGroupAsOrga(account2, "test", "hi", null, null, true, null, null, null);
List<Group> groups1 = userService.getUserGroups(new User(account2.getName(), account2.getGivenname(), account2.getFamilyname(), account2.getEmail()));
controllerService.createGroup(account, "test", "hi", null, true, true, null,groups1.get(0).getId());
controllerService.createGroup(account, "test", "hi", null, true, true, null, groups1.get(0).getId());
List<Group> groups = userService.getUserGroups(new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail()));
testTitleAndDescription(groups.get(0).getTitle(), groups.get(0).getDescription());
assertEquals(Visibility.PUBLIC, groups.get(0).getVisibility());

View File

@ -5,26 +5,23 @@ import mops.gruppen2.domain.dto.EventDTO;
import mops.gruppen2.domain.event.Event;
import mops.gruppen2.repository.EventRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
import static mops.gruppen2.TestBuilder.addUserEvent;
import static mops.gruppen2.TestBuilder.addUserEvents;
import static mops.gruppen2.TestBuilder.createPrivateGroupEvent;
import static mops.gruppen2.TestBuilder.createPrivateGroupEvents;
import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.createPublicGroupEvents;
import static mops.gruppen2.TestBuilder.updateGroupDescriptionEvent;
import static mops.gruppen2.TestBuilder.uuidFromInt;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
//TODO: Der ID autocounter wird nicht resettet -> Tests schlagen fehl beim nacheinanderausführen
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Gruppen2Application.class)
@Transactional
@ -33,14 +30,16 @@ class EventServiceTest {
@Autowired
private EventRepository eventRepository;
@Autowired
private JsonService jsonService;
private EventService eventService;
@Autowired
private JdbcTemplate template;
@BeforeEach
void setUp() {
eventService = new EventService(jsonService, eventRepository);
eventService = new EventService(eventRepository);
eventRepository.deleteAll();
//noinspection SqlResolve
template.execute("ALTER TABLE event ALTER COLUMN event_id RESTART WITH 1");
}
@Test
@ -79,20 +78,20 @@ class EventServiceTest {
@Test
void getEventsOfGroup() {
eventService.saveAll(addUserEvents(10, uuidFromInt(0)),
addUserEvents(5, uuidFromInt(1)));
eventService.saveAll(addUserEvents(10, uuidMock(0)),
addUserEvents(5, uuidMock(1)));
assertThat(eventService.getEventsOfGroup(uuidFromInt(0))).hasSize(10);
assertThat(eventService.getEventsOfGroup(uuidFromInt(1))).hasSize(5);
assertThat(eventService.getEventsOfGroup(uuidMock(0))).hasSize(10);
assertThat(eventService.getEventsOfGroup(uuidMock(1))).hasSize(5);
}
@Test
void findGroupIdsByUser() {
eventService.saveAll(addUserEvent(uuidFromInt(0), "A"),
addUserEvent(uuidFromInt(1), "A"),
addUserEvent(uuidFromInt(2), "A"),
addUserEvent(uuidFromInt(3), "A"),
addUserEvent(uuidFromInt(3), "B"));
eventService.saveAll(addUserEvent(uuidMock(0), "A"),
addUserEvent(uuidMock(1), "A"),
addUserEvent(uuidMock(2), "A"),
addUserEvent(uuidMock(3), "A"),
addUserEvent(uuidMock(3), "B"));
assertThat(eventService.findGroupIdsByUser("A")).hasSize(4);
assertThat(eventService.findGroupIdsByUser("B")).hasSize(1);

View File

@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
@ -30,7 +31,7 @@ import static mops.gruppen2.TestBuilder.createPublicGroupEvent;
import static mops.gruppen2.TestBuilder.deleteGroupEvent;
import static mops.gruppen2.TestBuilder.updateGroupDescriptionEvent;
import static mops.gruppen2.TestBuilder.updateGroupTitleEvent;
import static mops.gruppen2.TestBuilder.uuidFromInt;
import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@ -44,20 +45,20 @@ class GroupServiceTest {
@Autowired
private EventService eventService;
private GroupService groupService;
@Autowired
private JdbcTemplate template;
@BeforeEach
void setUp() {
groupService = new GroupService(eventService, eventRepository);
eventRepository.deleteAll();
//noinspection SqlResolve
template.execute("ALTER TABLE event ALTER COLUMN event_id RESTART WITH 1");
}
//TODO: Wofür ist dieser Test?
@Test
void rightClassForSuccessfulGroup() {
/*List<Event> eventList = new ArrayList<>();
UUID id = UUID.randomUUID();
eventList.add(new CreateGroupEvent(id, "Prof", null, GroupType.LECTURE, Visibility.PRIVATE, 1000L));
eventList.add(new AddUserEvent(id, "Ulli", "Ulli", "Honnis", "FC@B.de"));*/
List<Event> eventList = completePrivateGroup(1);
List<Group> groups = groupService.projectEventList(eventList);
@ -88,30 +89,21 @@ class GroupServiceTest {
@Test
void getGroupEvents() {
//CreateGroupEvent test1 = new CreateGroupEvent(uuidFromInt(0), "test1", null, GroupType.SIMPLE, Visibility.PUBLIC, 20L);
//CreateGroupEvent test2 = new CreateGroupEvent(uuidFromInt(1), "test2", null, GroupType.SIMPLE, Visibility.PUBLIC, 10L);
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
createPublicGroupEvent(uuidMock(1)),
createPrivateGroupEvent(uuidMock(2)));
eventService.saveAll(createPublicGroupEvent(uuidFromInt(0)),
createPublicGroupEvent(uuidFromInt(1)),
createPrivateGroupEvent(uuidFromInt(2)));
List<UUID> groupIds = Arrays.asList(uuidFromInt(0), uuidFromInt(1));
List<UUID> groupIds = Arrays.asList(uuidMock(0), uuidMock(1));
assertThat(groupService.getGroupEvents(groupIds)).hasSize(2);
assertThat(groupService.getGroupEvents(groupIds).get(0).getGroupId()).isEqualTo(uuidFromInt(0));
assertThat(groupService.getGroupEvents(groupIds).get(1).getGroupId()).isEqualTo(uuidFromInt(1));
assertThat(groupService.getGroupEvents(groupIds).get(0).getGroupId()).isEqualTo(uuidMock(0));
assertThat(groupService.getGroupEvents(groupIds).get(1).getGroupId()).isEqualTo(uuidMock(1));
}
@Test
void getAllGroupWithVisibilityPublicTestCreateAndDeleteSameGroup() {
//CreateGroupEvent test1 = new CreateGroupEvent(uuidFromInt(0), "test1", null, GroupType.SIMPLE, Visibility.PUBLIC, 20L);
//DeleteGroupEvent test2 = new DeleteGroupEvent(uuidFromInt(0), "test1");
Event test1 = createPublicGroupEvent(uuidFromInt(0));
Event test2 = deleteGroupEvent(uuidFromInt(0));
//Group group = new Group();
//test1.apply(group);
//test2.apply(group);
Event test1 = createPublicGroupEvent(uuidMock(0));
Event test2 = deleteGroupEvent(uuidMock(0));
//TODO: Hier projectEventlist()?
Group group = TestBuilder.apply(test1, test2);
@ -122,50 +114,31 @@ class GroupServiceTest {
@Test
void getAllGroupWithVisibilityPublicTestGroupPublic() {
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(0), "test1", null, GroupType.SIMPLE, Visibility.PUBLIC, 20L));
//eventService.saveEvent(new DeleteGroupEvent(uuidFromInt(0), "test1"));
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(1), "test2", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
//eventService.saveEvent(new UpdateRoleEvent(uuidFromInt(1), "test2", Role.MEMBER)); //Wofür ist das
eventService.saveAll(createPublicGroupEvent(uuidFromInt(0)),
deleteGroupEvent(uuidFromInt(0)),
createPublicGroupEvent());
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
deleteGroupEvent(uuidMock(0)),
createPublicGroupEvent());
assertThat(groupService.getAllGroupWithVisibilityPublic("test1").size()).isEqualTo(1);
}
@Test
void getAllGroupWithVisibilityPublicTestAddSomeEvents() {
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(0), "test1", null, GroupType.SIMPLE, Visibility.PUBLIC, 20L));
//eventService.saveEvent(new DeleteGroupEvent(uuidFromInt(0), "test1"));
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(1), "test2", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
//eventService.saveEvent(new UpdateRoleEvent(uuidFromInt(1), "test2", Role.MEMBER)); // Wofür?
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(2), "test3", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(3), "test4", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(4), "test5", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
eventService.saveAll(createPublicGroupEvent(uuidFromInt(0)),
deleteGroupEvent(uuidFromInt(0)),
createPublicGroupEvent(),
createPublicGroupEvent(),
createPublicGroupEvent(),
createPrivateGroupEvent());
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
deleteGroupEvent(uuidMock(0)),
createPublicGroupEvent(),
createPublicGroupEvent(),
createPublicGroupEvent(),
createPrivateGroupEvent());
assertThat(groupService.getAllGroupWithVisibilityPublic("test1").size()).isEqualTo(3);
}
@Test
void getAllGroupWithVisibilityPublic_UserInGroup() {
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(0), "test1", null, GroupType.SIMPLE, Visibility.PUBLIC, 20L));
//eventService.saveEvent(new AddUserEvent(uuidFromInt(0), "test1", "test", "test", "test@test"));
eventService.saveAll(createPublicGroupEvent(uuidFromInt(0)),
addUserEvent(uuidFromInt(0), "kobold"),
createPrivateGroupEvent(),
createPublicGroupEvent());
//Das kommt glaube ich eher in einen Test für die Projektion
//assertThat(groupService.getAllGroupWithVisibilityPublic("test2").get(0).getMembers().size()).isEqualTo(1);
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
addUserEvent(uuidMock(0), "kobold"),
createPrivateGroupEvent(),
createPublicGroupEvent());
assertThat(groupService.getAllGroupWithVisibilityPublic("kobold")).hasSize(1);
assertThat(groupService.getAllGroupWithVisibilityPublic("peter")).hasSize(2);
@ -173,56 +146,42 @@ class GroupServiceTest {
@Test
void getAllLecturesWithVisibilityPublic() {
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(0), "test1", null, GroupType.SIMPLE, Visibility.PUBLIC, 20L));
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(1), "test2", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
//eventService.saveEvent(new UpdateRoleEvent(uuidFromInt(1), "test2", Role.MEMBER)); // Hä
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(2), "test3", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(3), "test4", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(4), "test5", null, GroupType.LECTURE, Visibility.PUBLIC, 10L));
eventService.saveAll(createLectureEvent(),
createPublicGroupEvent(),
createLectureEvent(),
createLectureEvent(),
createLectureEvent());
createPublicGroupEvent(),
createLectureEvent(),
createLectureEvent(),
createLectureEvent());
assertThat(groupService.getAllLecturesWithVisibilityPublic().size()).isEqualTo(4);
}
@Test
void findGroupWith_UserMember_AllGroups() {
//eventService.saveEvent(new CreateGroupEvent(uuidFromInt(0), "test1", null, GroupType.SIMPLE, Visibility.PUBLIC, 20L));
//eventService.saveEvent(new AddUserEvent(uuidFromInt(0), "test1", "test", "test", "test@test"));
//eventService.saveEvent(new UpdateGroupTitleEvent(uuidFromInt(0), "test1", "TestGroup"));
//eventService.saveEvent(new UpdateGroupDescriptionEvent(uuidFromInt(0), "test1", "TestDescription"));
//eventService.saveEvent(new UpdateRoleEvent(uuidFromInt(0), "test1", Role.MEMBER));
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
addUserEvent(uuidMock(0), "jens"),
updateGroupTitleEvent(uuidMock(0)),
updateGroupDescriptionEvent(uuidMock(0)));
eventService.saveAll(createPublicGroupEvent(uuidFromInt(0)),
addUserEvent(uuidFromInt(0), "jens"),
updateGroupTitleEvent(uuidFromInt(0)),
updateGroupDescriptionEvent(uuidFromInt(0)));
//assertThat(groupService.findGroupWith("T", new Account("jens", "a@A", "test", "peter", "mueller", null)).size()).isEqualTo(1);
assertThat(groupService.findGroupWith("", account("jens"))).isEmpty();
}
@Test
void findGroupWith_UserNoMember_AllGroups() {
eventService.saveAll(completePublicGroups(10, 0),
completePrivateGroups(10, 0));
completePrivateGroups(10, 0));
assertThat(groupService.findGroupWith("", account("jens"))).hasSize(10);
}
@Test
void findGroupWith_FilterGroups() {
eventService.saveAll(createPublicGroupEvent(uuidFromInt(0)),
updateGroupTitleEvent(uuidFromInt(0), "KK"),
updateGroupDescriptionEvent(uuidFromInt(0), "ABCDE"),
createPublicGroupEvent(uuidFromInt(1)),
updateGroupTitleEvent(uuidFromInt(1), "ABCDEFG"),
updateGroupDescriptionEvent(uuidFromInt(1), "KK"),
createPrivateGroupEvent());
eventService.saveAll(createPublicGroupEvent(uuidMock(0)),
updateGroupTitleEvent(uuidMock(0), "KK"),
updateGroupDescriptionEvent(uuidMock(0), "ABCDE"),
createPublicGroupEvent(uuidMock(1)),
updateGroupTitleEvent(uuidMock(1), "ABCDEFG"),
updateGroupDescriptionEvent(uuidMock(1), "KK"),
createPrivateGroupEvent());
assertThat(groupService.findGroupWith("A", account("jesus"))).hasSize(2);
assertThat(groupService.findGroupWith("F", account("jesus"))).hasSize(1);