From a30d45821909d601cc48e360c85e336a09c5f665 Mon Sep 17 00:00:00 2001 From: LukasEttel Date: Thu, 12 Mar 2020 14:40:07 +0100 Subject: [PATCH 01/18] Created first Api implementation --- .../gruppen2/repository/EventRepository.java | 8 +++++-- .../mops/gruppen2/service/EventService.java | 17 ++++++++++++-- .../gruppen2/service/EventServiceTest.java | 23 +++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/main/java/mops/gruppen2/repository/EventRepository.java b/src/main/java/mops/gruppen2/repository/EventRepository.java index 57b39b5..d518286 100644 --- a/src/main/java/mops/gruppen2/repository/EventRepository.java +++ b/src/main/java/mops/gruppen2/repository/EventRepository.java @@ -1,14 +1,18 @@ package mops.gruppen2.repository; import mops.gruppen2.domain.EventDTO; -import mops.gruppen2.domain.event.Event; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface EventRepository extends CrudRepository { - @Query("SELECT * FROM event WHERE event_id > ?#{[0]}") + @Query("SELECT * FROM event WHERE event_id > @status") public Iterable findNewEventSinceStatus(@Param("status") Long status); + + @Query("SELECT * FROM event WHERE group_id IN @groupIds ") + public Iterable findAllEventsOfGroups(@Param("groupIds") List groupIds); } diff --git a/src/main/java/mops/gruppen2/service/EventService.java b/src/main/java/mops/gruppen2/service/EventService.java index aba10cc..4da92dd 100644 --- a/src/main/java/mops/gruppen2/service/EventService.java +++ b/src/main/java/mops/gruppen2/service/EventService.java @@ -55,9 +55,11 @@ public class EventService { public List getNewEvents(Long status){ - Iterable eventDTOS = eventStore.findNewEventSinceStatus(status); + Iterable newEventDTOS = eventStore.findNewEventSinceStatus(status); + List groupIdsThatChanged = this.getAllGroupIds(newEventDTOS); - return translateEventDTOs(eventDTOS); + Iterable groupEventDTOS = eventStore.findAllEventsOfGroups(groupIdsThatChanged); + return translateEventDTOs(groupEventDTOS); } private List translateEventDTOs(Iterable eventDTOS){ @@ -74,4 +76,15 @@ public class EventService { return events; } + private List getAllGroupIds(Iterable eventDTOS){ + List idsOfChangedGroups = new ArrayList<>(); + for (EventDTO eventDTO : eventDTOS){ + if (!idsOfChangedGroups.contains(eventDTO.getGroup_id())) { + idsOfChangedGroups.add(eventDTO.getGroup_id()); + + } + } + return idsOfChangedGroups; + } + } diff --git a/src/test/java/mops/gruppen2/service/EventServiceTest.java b/src/test/java/mops/gruppen2/service/EventServiceTest.java index a89540e..159bcf1 100644 --- a/src/test/java/mops/gruppen2/service/EventServiceTest.java +++ b/src/test/java/mops/gruppen2/service/EventServiceTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -37,4 +38,26 @@ class EventServiceTest { when(eventRepositoryMock.findAll()).thenReturn(eventDTOS); assertEquals(eventDTO1.getGroup_id()+1, eventService.checkGroup()); } + + @Test + void checkGetAllGroupIdsWithRepeadedId(){ + ArrayList eventDTOS = new ArrayList<>(); + + EventDTO eventDTO1 = new EventDTO(); + eventDTO1.setGroup_id(1L); + eventDTOS.add(eventDTO1); + + EventDTO eventDTO2 = new EventDTO(); + eventDTO2.setGroup_id(2L); + eventDTOS.add(eventDTO2); + + EventDTO eventDTO3 = new EventDTO(); + eventDTO3.setGroup_id(1L); + eventDTOS.add(eventDTO3); + + List groupIds = eventService.getAllGroupIds(eventDTOS); + + assertThat(groupIds.size()).isEqualTo(2); + + } } \ No newline at end of file From 9795c10c148dd0813e72ff29dd6868dc498a4856 Mon Sep 17 00:00:00 2001 From: LukasEttel Date: Thu, 12 Mar 2020 16:11:32 +0100 Subject: [PATCH 02/18] Impletended the updategroup(status) method in the API --- .../mops/gruppen2/Gruppen2Application.java | 2 +- .../gruppen2/controller/APIController.java | 10 +++++++-- .../apiWrapper/UpdatedGroupRequestMapper.java | 16 ++++++++++++++ .../gruppen2/repository/EventRepository.java | 7 ++++-- .../mops/gruppen2/service/APIFormatter.java | 12 ++++++++++ .../mops/gruppen2/service/EventService.java | 4 ++++ .../gruppen2/service/EventServiceTest.java | 22 ------------------- 7 files changed, 46 insertions(+), 27 deletions(-) create mode 100644 src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java create mode 100644 src/main/java/mops/gruppen2/service/APIFormatter.java diff --git a/src/main/java/mops/gruppen2/Gruppen2Application.java b/src/main/java/mops/gruppen2/Gruppen2Application.java index 8261158..8127e46 100644 --- a/src/main/java/mops/gruppen2/Gruppen2Application.java +++ b/src/main/java/mops/gruppen2/Gruppen2Application.java @@ -32,7 +32,7 @@ public class Gruppen2Application { public Docket productAPI() { return new Docket(DocumentationType.SWAGGER_2) .select() - .paths(PathSelectors.ant("/products/**")) + .paths(PathSelectors.ant("/gruppen2/**")) .apis(RequestHandlerSelectors.basePackage("mops.gruppen2")) .build() .apiInfo(apiMetadata()); diff --git a/src/main/java/mops/gruppen2/controller/APIController.java b/src/main/java/mops/gruppen2/controller/APIController.java index 832f6b3..940d7f1 100644 --- a/src/main/java/mops/gruppen2/controller/APIController.java +++ b/src/main/java/mops/gruppen2/controller/APIController.java @@ -1,13 +1,17 @@ package mops.gruppen2.controller; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.javafaker.Faker; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import mops.gruppen2.domain.Exceptions.EventException; import mops.gruppen2.domain.Group; import mops.gruppen2.domain.ProductSwaggerExample; +import mops.gruppen2.domain.apiWrapper.UpdatedGroupRequestMapper; import mops.gruppen2.domain.event.Event; +import mops.gruppen2.service.APIFormatter; import mops.gruppen2.service.EventService; import mops.gruppen2.service.GroupService; import mops.gruppen2.service.SerializationService; @@ -35,9 +39,11 @@ public class APIController { @GetMapping("/updatedGroups/{status}") @ApiOperation(value = "Gibt alle Gruppen zurück in denen sich etwas geändert hat") - public List updateGroup(@ApiParam("Status des Anfragestellers") @PathVariable Long status) throws EventException { + public UpdatedGroupRequestMapper updateGroup(@ApiParam("Status des Anfragestellers") @PathVariable Long status) throws EventException, JsonProcessingException { List events = eventService.getNewEvents(status); - return groupService.projectEventList(events); + UpdatedGroupRequestMapper updatedGroupRequestMapper = APIFormatter.wrapp(eventService.getMaxEvent_id(), groupService.projectEventList(events)); + + return updatedGroupRequestMapper; } diff --git a/src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java b/src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java new file mode 100644 index 0000000..ae9c4f3 --- /dev/null +++ b/src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java @@ -0,0 +1,16 @@ +package mops.gruppen2.domain.apiWrapper; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import mops.gruppen2.domain.Group; + +import java.util.List; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class UpdatedGroupRequestMapper { + private Long status; + private List groupList; +} diff --git a/src/main/java/mops/gruppen2/repository/EventRepository.java b/src/main/java/mops/gruppen2/repository/EventRepository.java index d518286..04112ae 100644 --- a/src/main/java/mops/gruppen2/repository/EventRepository.java +++ b/src/main/java/mops/gruppen2/repository/EventRepository.java @@ -10,9 +10,12 @@ import java.util.List; @Repository public interface EventRepository extends CrudRepository { - @Query("SELECT * FROM event WHERE event_id > @status") + @Query("SELECT * FROM event WHERE event_id > :status") public Iterable findNewEventSinceStatus(@Param("status") Long status); - @Query("SELECT * FROM event WHERE group_id IN @groupIds ") + @Query("SELECT * FROM event WHERE group_id IN (:groupIds) ") public Iterable findAllEventsOfGroups(@Param("groupIds") List groupIds); + + @Query("SELECT MAX(event_id) FROM event") + public Long getHighesEvent_ID(); } diff --git a/src/main/java/mops/gruppen2/service/APIFormatter.java b/src/main/java/mops/gruppen2/service/APIFormatter.java new file mode 100644 index 0000000..c18c6e9 --- /dev/null +++ b/src/main/java/mops/gruppen2/service/APIFormatter.java @@ -0,0 +1,12 @@ +package mops.gruppen2.service; + +import mops.gruppen2.domain.Group; +import mops.gruppen2.domain.apiWrapper.UpdatedGroupRequestMapper; + +import java.util.List; + +public class APIFormatter { + static public UpdatedGroupRequestMapper wrapp(Long status, List groupList){ + return new UpdatedGroupRequestMapper(status, groupList); + } +} diff --git a/src/main/java/mops/gruppen2/service/EventService.java b/src/main/java/mops/gruppen2/service/EventService.java index 4da92dd..1552a5b 100644 --- a/src/main/java/mops/gruppen2/service/EventService.java +++ b/src/main/java/mops/gruppen2/service/EventService.java @@ -87,4 +87,8 @@ public class EventService { return idsOfChangedGroups; } + public Long getMaxEvent_id(){ + return eventStore.getHighesEvent_ID(); + } + } diff --git a/src/test/java/mops/gruppen2/service/EventServiceTest.java b/src/test/java/mops/gruppen2/service/EventServiceTest.java index 159bcf1..77a2b7b 100644 --- a/src/test/java/mops/gruppen2/service/EventServiceTest.java +++ b/src/test/java/mops/gruppen2/service/EventServiceTest.java @@ -38,26 +38,4 @@ class EventServiceTest { when(eventRepositoryMock.findAll()).thenReturn(eventDTOS); assertEquals(eventDTO1.getGroup_id()+1, eventService.checkGroup()); } - - @Test - void checkGetAllGroupIdsWithRepeadedId(){ - ArrayList eventDTOS = new ArrayList<>(); - - EventDTO eventDTO1 = new EventDTO(); - eventDTO1.setGroup_id(1L); - eventDTOS.add(eventDTO1); - - EventDTO eventDTO2 = new EventDTO(); - eventDTO2.setGroup_id(2L); - eventDTOS.add(eventDTO2); - - EventDTO eventDTO3 = new EventDTO(); - eventDTO3.setGroup_id(1L); - eventDTOS.add(eventDTO3); - - List groupIds = eventService.getAllGroupIds(eventDTOS); - - assertThat(groupIds.size()).isEqualTo(2); - - } } \ No newline at end of file From 4e874bf6e21cac532f54087185bfe528a95ebd3f Mon Sep 17 00:00:00 2001 From: LukasEttel Date: Thu, 12 Mar 2020 16:27:52 +0100 Subject: [PATCH 03/18] Impletended the updategroup(status) method in the API --- .../java/mops/gruppen2/controller/APIController.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/mops/gruppen2/controller/APIController.java b/src/main/java/mops/gruppen2/controller/APIController.java index 940d7f1..92d4de2 100644 --- a/src/main/java/mops/gruppen2/controller/APIController.java +++ b/src/main/java/mops/gruppen2/controller/APIController.java @@ -39,12 +39,20 @@ public class APIController { @GetMapping("/updatedGroups/{status}") @ApiOperation(value = "Gibt alle Gruppen zurück in denen sich etwas geändert hat") - public UpdatedGroupRequestMapper updateGroup(@ApiParam("Status des Anfragestellers") @PathVariable Long status) throws EventException, JsonProcessingException { + public UpdatedGroupRequestMapper updateGroup(@ApiParam("Status des Anfragestellers") @PathVariable Long status) throws EventException { List events = eventService.getNewEvents(status); UpdatedGroupRequestMapper updatedGroupRequestMapper = APIFormatter.wrapp(eventService.getMaxEvent_id(), groupService.projectEventList(events)); return updatedGroupRequestMapper; } + @GetMapping("/getGroups/{teilnehme}") + @ApiOperation(value = "Gibt alle Gruppen zurück in denen sich ein Teilnehmer befindet") + public List getGroupsOfUser(@ApiParam("Der Teilnehmer") @PathVariable String userId) throws EventException { + List asd = new ArrayList<>(); + + return asd; + } + } From 6b788beb4b4e0a92b652b330ac08c1bb19870bd3 Mon Sep 17 00:00:00 2001 From: XXNitram Date: Fri, 13 Mar 2020 13:46:34 +0100 Subject: [PATCH 04/18] Refactor ControllerService and add an UpdateRoleEvent to createGroup --- .../domain/event/UpdateRoleEvent.java | 4 +++ .../gruppen2/service/ControllerService.java | 29 +++++++++++++------ .../mops/gruppen2/service/EventService.java | 11 +++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java b/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java index a4301de..1627f08 100644 --- a/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java @@ -15,7 +15,11 @@ public class UpdateRoleEvent extends Event { public UpdateRoleEvent(Long event_id, Long group_id, String user_id, Role newRole) { super(event_id, group_id, user_id); + this.newRole = newRole; + } + public UpdateRoleEvent(Long group_id, String user_id, Role newRole) { + super(group_id, user_id); this.newRole = newRole; } } diff --git a/src/main/java/mops/gruppen2/service/ControllerService.java b/src/main/java/mops/gruppen2/service/ControllerService.java index 75f0b78..10e0f7b 100644 --- a/src/main/java/mops/gruppen2/service/ControllerService.java +++ b/src/main/java/mops/gruppen2/service/ControllerService.java @@ -1,10 +1,12 @@ package mops.gruppen2.service; import mops.gruppen2.domain.GroupType; +import mops.gruppen2.domain.Role; import mops.gruppen2.domain.Visibility; import mops.gruppen2.domain.event.*; import mops.gruppen2.security.Account; import org.springframework.stereotype.Service; +import java.util.*; @Service public class ControllerService { @@ -15,15 +17,24 @@ public class ControllerService { this.eventService = eventService; } - public void createGroup(Account account, String title, String beschreibung) { - CreateGroupEvent createGroupEvent = new CreateGroupEvent(eventService.checkGroup(), account.getName(), null , GroupType.LECTURE, Visibility.PUBLIC); - AddUserEvent addUserEvent = new AddUserEvent(eventService.checkGroup(), account.getName(),account.getGivenname(),account.getFamilyname(),account.getEmail()); - UpdateGroupTitleEvent updateGroupTitleEvent = new UpdateGroupTitleEvent(eventService.checkGroup(), account.getName(), title); - UpdateGroupDescriptionEvent updateGroupDescriptionEvent = new UpdateGroupDescriptionEvent(eventService.checkGroup(), account.getName(), beschreibung); + /** + * 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. + * + * @param account Keycloak-Account + * @param title Gruppentitel + * @param description Gruppenbeschreibung + */ + public void createGroup(Account account, String title, String description) { - eventService.saveEvent(createGroupEvent); - eventService.saveEvent(addUserEvent); - eventService.saveEvent(updateGroupTitleEvent); - eventService.saveEvent(updateGroupDescriptionEvent); + List eventList = new ArrayList<>(); + Collections.addAll(eventList, new CreateGroupEvent(eventService.checkGroup(), account.getName(), null , GroupType.LECTURE, Visibility.PUBLIC), + new AddUserEvent(eventService.checkGroup(), account.getName(),account.getGivenname(),account.getFamilyname(),account.getEmail()), + new UpdateRoleEvent(eventService.checkGroup(), account.getName(), Role.ADMIN), + new UpdateGroupTitleEvent(eventService.checkGroup(), account.getName(), title), + new UpdateGroupDescriptionEvent(eventService.checkGroup(), account.getName(), description)); + + eventService.saveEventList(eventList); } } diff --git a/src/main/java/mops/gruppen2/service/EventService.java b/src/main/java/mops/gruppen2/service/EventService.java index cb4a0c9..6007bc5 100644 --- a/src/main/java/mops/gruppen2/service/EventService.java +++ b/src/main/java/mops/gruppen2/service/EventService.java @@ -94,4 +94,15 @@ public class EventService { return events; } + /** + * Sichert eine Liste von Event Objekten mithilfe der Methode saveEvent(Event event) + * + * @param createGroupEvents Liste von Event Objekten + */ + public void saveEventList(List createGroupEvents) { + for(Event event : createGroupEvents) { + saveEvent(event); + } + } + } From 26f26a1c1a247a7a01724e898dbc194e2e1e3bca Mon Sep 17 00:00:00 2001 From: XXNitram Date: Fri, 13 Mar 2020 13:47:05 +0100 Subject: [PATCH 05/18] Add JavaDoc comments to SerializationService --- .../gruppen2/service/SerializationService.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/mops/gruppen2/service/SerializationService.java b/src/main/java/mops/gruppen2/service/SerializationService.java index 1737ccc..04a6d47 100644 --- a/src/main/java/mops/gruppen2/service/SerializationService.java +++ b/src/main/java/mops/gruppen2/service/SerializationService.java @@ -22,11 +22,25 @@ public class SerializationService { this.eventStore = eventStore; } + /** + * Ü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 + */ public String serializeEvent(Event event) throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(event); } - + + /** + * Ü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 + */ public Event deserializeEvent(String json) throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(json, Event.class); From d1f296129d7368c0ef306d0054b3242bff3c7346 Mon Sep 17 00:00:00 2001 From: LukasEttel Date: Fri, 13 Mar 2020 13:50:49 +0100 Subject: [PATCH 06/18] Impletended SwaggerApi with all provisionally funktiontionallitys --- .../gruppen2/controller/APIController.java | 26 +++++++++---------- .../gruppen2/repository/EventRepository.java | 6 ++--- ...ormatter.java => APIFormatterService.java} | 4 ++- .../mops/gruppen2/service/EventService.java | 25 ++++++++---------- 4 files changed, 30 insertions(+), 31 deletions(-) rename src/main/java/mops/gruppen2/service/{APIFormatter.java => APIFormatterService.java} (77%) diff --git a/src/main/java/mops/gruppen2/controller/APIController.java b/src/main/java/mops/gruppen2/controller/APIController.java index 92d4de2..93bcc90 100644 --- a/src/main/java/mops/gruppen2/controller/APIController.java +++ b/src/main/java/mops/gruppen2/controller/APIController.java @@ -1,23 +1,18 @@ package mops.gruppen2.controller; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.javafaker.Faker; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import mops.gruppen2.domain.Exceptions.EventException; import mops.gruppen2.domain.Group; -import mops.gruppen2.domain.ProductSwaggerExample; import mops.gruppen2.domain.apiWrapper.UpdatedGroupRequestMapper; import mops.gruppen2.domain.event.Event; -import mops.gruppen2.service.APIFormatter; +import mops.gruppen2.service.APIFormatterService; import mops.gruppen2.service.EventService; import mops.gruppen2.service.GroupService; import mops.gruppen2.service.SerializationService; import org.springframework.web.bind.annotation.*; -import java.util.ArrayList; import java.util.List; /** @@ -37,22 +32,27 @@ public class APIController { this.groupService = groupService; } - @GetMapping("/updatedGroups/{status}") + @GetMapping("/updateGroups/{status}") @ApiOperation(value = "Gibt alle Gruppen zurück in denen sich etwas geändert hat") public UpdatedGroupRequestMapper updateGroup(@ApiParam("Status des Anfragestellers") @PathVariable Long status) throws EventException { List events = eventService.getNewEvents(status); - UpdatedGroupRequestMapper updatedGroupRequestMapper = APIFormatter.wrapp(eventService.getMaxEvent_id(), groupService.projectEventList(events)); + UpdatedGroupRequestMapper updatedGroupRequestMapper = APIFormatterService.wrapp(eventService.getMaxEvent_id(), groupService.projectEventList(events)); return updatedGroupRequestMapper; } - @GetMapping("/getGroups/{teilnehme}") + @GetMapping("/getGroupIdsOfUser/{teilnehmer}") @ApiOperation(value = "Gibt alle Gruppen zurück in denen sich ein Teilnehmer befindet") - public List getGroupsOfUser(@ApiParam("Der Teilnehmer") @PathVariable String userId) throws EventException { - List asd = new ArrayList<>(); - - return asd; + public List getGroupsOfUser(@ApiParam("Der Teilnehmer") @PathVariable String teilnehmer) throws EventException { + return eventService.getGroupsOfUser(teilnehmer); } + @GetMapping("/getGroup/{groupId}") + @ApiOperation(value = "Gibt alle die Gruppe mit der als Parameter mitgegebenden groupId zurück") + public Group getGroupFromId(@ApiParam("Die GruppenId der gefordeten Gruppe") @PathVariable Long groupId) throws EventException{ + List eventList = eventService.getEventsOfGroup(groupId); + List groups = groupService.projectEventList(eventList); + return groups.get(0); + } } diff --git a/src/main/java/mops/gruppen2/repository/EventRepository.java b/src/main/java/mops/gruppen2/repository/EventRepository.java index 609b417..6629440 100644 --- a/src/main/java/mops/gruppen2/repository/EventRepository.java +++ b/src/main/java/mops/gruppen2/repository/EventRepository.java @@ -16,11 +16,11 @@ public interface EventRepository extends CrudRepository { @Query("select * from event where group_id =:id") List findEventDTOByGroup_id(@Param("id") Long group_id); - @Query("SELECT * FROM event WHERE event_id > :status") - public Iterable findNewEventSinceStatus(@Param("status") Long status); + @Query("SELECT DISTINCT group_id FROM event WHERE event_id > :status") + public List findNewEventSinceStatus(@Param("status") Long status); @Query("SELECT * FROM event WHERE group_id IN (:groupIds) ") - public Iterable findAllEventsOfGroups(@Param("groupIds") List groupIds); + public List findAllEventsOfGroups(@Param("groupIds") List groupIds); @Query("SELECT MAX(event_id) FROM event") public Long getHighesEvent_ID(); diff --git a/src/main/java/mops/gruppen2/service/APIFormatter.java b/src/main/java/mops/gruppen2/service/APIFormatterService.java similarity index 77% rename from src/main/java/mops/gruppen2/service/APIFormatter.java rename to src/main/java/mops/gruppen2/service/APIFormatterService.java index c18c6e9..5665bdf 100644 --- a/src/main/java/mops/gruppen2/service/APIFormatter.java +++ b/src/main/java/mops/gruppen2/service/APIFormatterService.java @@ -2,10 +2,12 @@ package mops.gruppen2.service; import mops.gruppen2.domain.Group; import mops.gruppen2.domain.apiWrapper.UpdatedGroupRequestMapper; +import org.springframework.stereotype.Service; import java.util.List; -public class APIFormatter { +@Service +public class APIFormatterService { static public UpdatedGroupRequestMapper wrapp(Long status, List groupList){ return new UpdatedGroupRequestMapper(status, groupList); } diff --git a/src/main/java/mops/gruppen2/service/EventService.java b/src/main/java/mops/gruppen2/service/EventService.java index c958493..e45644d 100644 --- a/src/main/java/mops/gruppen2/service/EventService.java +++ b/src/main/java/mops/gruppen2/service/EventService.java @@ -70,10 +70,9 @@ public class EventService { * @return Liste von Events */ public List getNewEvents(Long status){ - Iterable newEventDTOS = eventStore.findNewEventSinceStatus(status); - List groupIdsThatChanged = this.getAllGroupIds(newEventDTOS); + List groupIdsThatChanged = eventStore.findNewEventSinceStatus(status); - Iterable groupEventDTOS = eventStore.findAllEventsOfGroups(groupIdsThatChanged); + List groupEventDTOS = eventStore.findAllEventsOfGroups(groupIdsThatChanged); return translateEventDTOs(groupEventDTOS); } @@ -96,19 +95,17 @@ public class EventService { return events; } - private List getAllGroupIds(Iterable eventDTOS){ - List idsOfChangedGroups = new ArrayList<>(); - for (EventDTO eventDTO : eventDTOS){ - if (!idsOfChangedGroups.contains(eventDTO.getGroup_id())) { - idsOfChangedGroups.add(eventDTO.getGroup_id()); - - } - } - return idsOfChangedGroups; - } - public Long getMaxEvent_id(){ return eventStore.getHighesEvent_ID(); } + public List getGroupsOfUser(String userID) { + return eventStore.findGroup_idsWhereUser_id(userID); + } + + public List getEventsOfGroup(Long groupId) { + List eventDTOList = eventStore.findEventDTOByGroup_id(groupId); + return translateEventDTOs(eventDTOList); + } + } From 7bbdbad28ea68d6e27bc4f56744bd50a96b22d0c Mon Sep 17 00:00:00 2001 From: kasch309 Date: Fri, 13 Mar 2020 14:27:38 +0100 Subject: [PATCH 07/18] Add details.html to display group details --- src/main/resources/templates/details.html | 53 +++++++++++++++++++++++ src/main/resources/templates/index.html | 2 +- 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/templates/details.html diff --git a/src/main/resources/templates/details.html b/src/main/resources/templates/details.html new file mode 100644 index 0000000..07ffc05 --- /dev/null +++ b/src/main/resources/templates/details.html @@ -0,0 +1,53 @@ + + + + + Name des Subsystems + + + + + +
+ +
+
+
+
+
+

+

+ , + +

+

+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 822ebf1..ba20b5a 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -31,7 +31,7 @@

- +

From eeded221b472332a41e2e63245cbb3ce39d84553 Mon Sep 17 00:00:00 2001 From: kasch309 Date: Fri, 13 Mar 2020 14:28:16 +0100 Subject: [PATCH 08/18] Add method to find group by id Add method to connect details.html to the controller --- .../java/mops/gruppen2/controller/Gruppen2Controller.java | 7 +++++++ src/main/java/mops/gruppen2/service/UserService.java | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java b/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java index 96ec538..271f02c 100644 --- a/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java +++ b/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java @@ -83,4 +83,11 @@ public class Gruppen2Controller { return "redirect:/gruppen2/"; } + @GetMapping("/details") + public String showGroupDetails(KeycloakAuthenticationToken token, Model model, @RequestParam (value="group_id") Long group_id) throws EventException { + model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token)); + model.addAttribute("group", userService.getGroupById(group_id)); + return "details"; + } + } diff --git a/src/main/java/mops/gruppen2/service/UserService.java b/src/main/java/mops/gruppen2/service/UserService.java index bfe8b37..7fe6122 100644 --- a/src/main/java/mops/gruppen2/service/UserService.java +++ b/src/main/java/mops/gruppen2/service/UserService.java @@ -6,6 +6,7 @@ import mops.gruppen2.domain.event.Event; import mops.gruppen2.repository.EventRepository; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; @Service @@ -26,4 +27,11 @@ public class UserService { List events = groupService.getGroupEvents(group_ids); return groupService.projectEventList(events); } + + public Group getGroupById(Long group_id) throws EventException { + List group_ids = new ArrayList<>(); + group_ids.add(group_id); + List events = groupService.getGroupEvents(group_ids); + return groupService.projectEventList(events).get(0); + } } From 8ce3fc39b1e701986ba0414cebd1a1a999149e4a Mon Sep 17 00:00:00 2001 From: LukasEttel Date: Fri, 13 Mar 2020 14:42:17 +0100 Subject: [PATCH 09/18] quick refactor --- src/main/java/mops/gruppen2/Gruppen2Application.java | 2 +- .../java/mops/gruppen2/controller/APIController.java | 10 +++++----- src/main/java/mops/gruppen2/domain/Group.java | 4 ++-- src/test/java/mops/gruppen2/domain/GroupTest.java | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/mops/gruppen2/Gruppen2Application.java b/src/main/java/mops/gruppen2/Gruppen2Application.java index 8127e46..1566a63 100644 --- a/src/main/java/mops/gruppen2/Gruppen2Application.java +++ b/src/main/java/mops/gruppen2/Gruppen2Application.java @@ -32,7 +32,7 @@ public class Gruppen2Application { public Docket productAPI() { return new Docket(DocumentationType.SWAGGER_2) .select() - .paths(PathSelectors.ant("/gruppen2/**")) + .paths(PathSelectors.ant("/gruppen2/api/**")) .apis(RequestHandlerSelectors.basePackage("mops.gruppen2")) .build() .apiInfo(apiMetadata()); diff --git a/src/main/java/mops/gruppen2/controller/APIController.java b/src/main/java/mops/gruppen2/controller/APIController.java index 93bcc90..f4d18ef 100644 --- a/src/main/java/mops/gruppen2/controller/APIController.java +++ b/src/main/java/mops/gruppen2/controller/APIController.java @@ -19,7 +19,7 @@ import java.util.List; * Ein Beispiel für eine API mit Swagger. */ @RestController -@RequestMapping("/gruppen2") +@RequestMapping("/gruppen2/api") public class APIController { private final SerializationService serializationService; @@ -34,7 +34,7 @@ public class APIController { @GetMapping("/updateGroups/{status}") @ApiOperation(value = "Gibt alle Gruppen zurück in denen sich etwas geändert hat") - public UpdatedGroupRequestMapper updateGroup(@ApiParam("Status des Anfragestellers") @PathVariable Long status) throws EventException { + public UpdatedGroupRequestMapper updateGroup(@ApiParam("Letzter Status des Anfragestellers") @PathVariable Long status) throws EventException { List events = eventService.getNewEvents(status); UpdatedGroupRequestMapper updatedGroupRequestMapper = APIFormatterService.wrapp(eventService.getMaxEvent_id(), groupService.projectEventList(events)); @@ -43,13 +43,13 @@ public class APIController { @GetMapping("/getGroupIdsOfUser/{teilnehmer}") @ApiOperation(value = "Gibt alle Gruppen zurück in denen sich ein Teilnehmer befindet") - public List getGroupsOfUser(@ApiParam("Der Teilnehmer") @PathVariable String teilnehmer) throws EventException { + public List getGroupsOfUser(@ApiParam("Teilnehmer dessen groupIds zurückgegeben werden sollen") @PathVariable String teilnehmer) throws EventException { return eventService.getGroupsOfUser(teilnehmer); } @GetMapping("/getGroup/{groupId}") - @ApiOperation(value = "Gibt alle die Gruppe mit der als Parameter mitgegebenden groupId zurück") - public Group getGroupFromId(@ApiParam("Die GruppenId der gefordeten Gruppe") @PathVariable Long groupId) throws EventException{ + @ApiOperation(value = "Gibt die Gruppe mit der als Parameter mitgegebenden groupId zurück") + public Group getGroupFromId(@ApiParam("GruppenId der gefordeten Gruppe") @PathVariable Long groupId) throws EventException{ List eventList = eventService.getEventsOfGroup(groupId); List groups = groupService.projectEventList(eventList); diff --git a/src/main/java/mops/gruppen2/domain/Group.java b/src/main/java/mops/gruppen2/domain/Group.java index e4929d1..6e2f6ac 100644 --- a/src/main/java/mops/gruppen2/domain/Group.java +++ b/src/main/java/mops/gruppen2/domain/Group.java @@ -17,7 +17,7 @@ public class Group extends Aggregate { private String title; private String description; private final List members; - private final Map roles; + private final Map roles; private GroupType type; private Visibility visibility; @@ -51,7 +51,7 @@ public class Group extends Aggregate { if (roles.containsKey(user) && event.getNewRole() == Role.MEMBER) { roles.remove(user); } else { - roles.put(user, event.getNewRole()); + roles.put(user.getUser_id(), event.getNewRole()); } } diff --git a/src/test/java/mops/gruppen2/domain/GroupTest.java b/src/test/java/mops/gruppen2/domain/GroupTest.java index 45a03ab..c3ed89d 100644 --- a/src/test/java/mops/gruppen2/domain/GroupTest.java +++ b/src/test/java/mops/gruppen2/domain/GroupTest.java @@ -115,7 +115,7 @@ class GroupTest { // Assert assertThat(group.getRoles()) - .containsOnlyKeys(group.getMembers().get(0)) + .containsOnlyKeys(group.getMembers().get(0).getUser_id()) .containsValue(Role.ADMIN); } From 68fcc06a174e564f9b6a01e746901d530a5cc2d2 Mon Sep 17 00:00:00 2001 From: killerber4t Date: Fri, 13 Mar 2020 15:11:23 +0100 Subject: [PATCH 10/18] add details page --- .../gruppen2/controller/Gruppen2Controller.java | 14 +++++++++++--- .../apiWrapper/UpdatedGroupRequestMapper.java | 16 ++++++++++++++++ src/main/resources/templates/index.html | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java diff --git a/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java b/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java index 271f02c..b71ca19 100644 --- a/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java +++ b/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java @@ -2,6 +2,7 @@ package mops.gruppen2.controller; import mops.gruppen2.config.Gruppen2Config; import mops.gruppen2.domain.Exceptions.EventException; +import mops.gruppen2.domain.Group; import mops.gruppen2.domain.GroupType; import mops.gruppen2.domain.User; import mops.gruppen2.domain.Visibility; @@ -13,9 +14,11 @@ import mops.gruppen2.security.Account; import mops.gruppen2.service.*; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ResponseStatusException; import javax.annotation.security.RolesAllowed; @@ -83,11 +86,16 @@ public class Gruppen2Controller { return "redirect:/gruppen2/"; } + @RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"}) @GetMapping("/details") - public String showGroupDetails(KeycloakAuthenticationToken token, Model model, @RequestParam (value="group_id") Long group_id) throws EventException { + public String showGroupDetails(KeycloakAuthenticationToken token, Model model, @RequestParam (value="id") Long id) throws EventException, ResponseStatusException { model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token)); - model.addAttribute("group", userService.getGroupById(group_id)); - return "details"; + Group group = userService.getGroupById(id); + if(group!= null) { + model.addAttribute("group", group); + return "details"; + } + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Group not found"); } } diff --git a/src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java b/src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java new file mode 100644 index 0000000..a8b73dc --- /dev/null +++ b/src/main/java/mops/gruppen2/domain/apiWrapper/UpdatedGroupRequestMapper.java @@ -0,0 +1,16 @@ +package mops.gruppen2.domain.apiWrapper; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import mops.gruppen2.domain.Group; + +import java.util.List; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class UpdatedGroupRequestMapper { + private Long status; + private List groupList; +} diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index ba20b5a..631364c 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -31,7 +31,7 @@

- +

From 86622b4a0cdcff50fcbb2f6cd988ef26cc7db87b Mon Sep 17 00:00:00 2001 From: kasch309 Date: Fri, 13 Mar 2020 16:07:12 +0100 Subject: [PATCH 11/18] add cases for different roles and visibility --- .../controller/Gruppen2Controller.java | 14 +++++------ .../{details.html => detailsMember.html} | 24 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) rename src/main/resources/templates/{details.html => detailsMember.html} (62%) diff --git a/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java b/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java index b71ca19..12d397e 100644 --- a/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java +++ b/src/main/java/mops/gruppen2/controller/Gruppen2Controller.java @@ -3,13 +3,8 @@ package mops.gruppen2.controller; import mops.gruppen2.config.Gruppen2Config; import mops.gruppen2.domain.Exceptions.EventException; import mops.gruppen2.domain.Group; -import mops.gruppen2.domain.GroupType; +import mops.gruppen2.domain.Role; import mops.gruppen2.domain.User; -import mops.gruppen2.domain.Visibility; -import mops.gruppen2.domain.event.AddUserEvent; -import mops.gruppen2.domain.event.CreateGroupEvent; -import mops.gruppen2.domain.event.UpdateGroupDescriptionEvent; -import mops.gruppen2.domain.event.UpdateGroupTitleEvent; import mops.gruppen2.security.Account; import mops.gruppen2.service.*; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; @@ -21,6 +16,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ResponseStatusException; import javax.annotation.security.RolesAllowed; +import java.util.Set; @Controller @RequestMapping("/gruppen2") @@ -91,9 +87,13 @@ public class Gruppen2Controller { public String showGroupDetails(KeycloakAuthenticationToken token, Model model, @RequestParam (value="id") Long id) throws EventException, ResponseStatusException { model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token)); Group group = userService.getGroupById(id); + Account account = keyCloakService.createAccountFromPrincipal (token); + User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail()); + Role role = group.getRoles().get(user); if(group!= null) { model.addAttribute("group", group); - return "details"; + model.addAttribute("role",role); + return "detailsMember"; } throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Group not found"); } diff --git a/src/main/resources/templates/details.html b/src/main/resources/templates/detailsMember.html similarity index 62% rename from src/main/resources/templates/details.html rename to src/main/resources/templates/detailsMember.html index 07ffc05..c912c5a 100644 --- a/src/main/resources/templates/details.html +++ b/src/main/resources/templates/detailsMember.html @@ -29,22 +29,24 @@

-

- , - +

From a1cc13eb00982b668ad7777b3e96a0c22ce4af2e Mon Sep 17 00:00:00 2001 From: killerber4t Date: Fri, 13 Mar 2020 16:08:47 +0100 Subject: [PATCH 12/18] change create --- src/main/resources/templates/create.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/create.html b/src/main/resources/templates/create.html index 00908f0..dbfabb9 100644 --- a/src/main/resources/templates/create.html +++ b/src/main/resources/templates/create.html @@ -37,7 +37,7 @@
-
+
From e48c1a78bb1f666e04e7ce6562d4236bdd4e832d Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 13 Mar 2020 16:10:16 +0100 Subject: [PATCH 13/18] update readme --- README.adoc | 237 ++++++++++------------------------------------------ 1 file changed, 44 insertions(+), 193 deletions(-) diff --git a/README.adoc b/README.adoc index 7e3552b..329e7be 100644 --- a/README.adoc +++ b/README.adoc @@ -1,214 +1,65 @@ -= Softwareentwicklung im Team: Vorbereitung auf das Projekt -WS19/20 -:icons: font -:icon-set: octicon -:source-highlighter: rouge -ifdef::env-github[] -:tip-caption: :bulb: -:note-caption: :information_source: -:important-caption: :heavy_exclamation_mark: -:caution-caption: :fire: -:warning-caption: :warning: -endif::[] += Gruppenbildung -== 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. -Für das Abschlussprojekt bilden Sie bitte eine Gruppe im GitHub Classroom, die -aus 7 bis 9 Personen besteht und laden eine entsprechende `group.yml` in AUAS -hoch. Im Gegensatz zu den normalen Blättern haben Sie volle -Administrationsrechte und alle Projekte sind öffentlich um den Austausch mit -anderen Gruppen bei Integrationen zwischen Anwendungen einfacher zu gestalten. +=== Problem -IMPORTANT: Bitte entfernen Sie nicht die Organisatoren aus Ihrem Projekt. +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. -NOTE: Sie finden neben dieser README eine -link:group.yml[Beispiel-Gruppe-YML-Datei]. Füllen Sie diese aus, checken Sie -sie ein. +=== Ziele -IMPORTANT: Erstellen Sie direkt eine Abgabe in AUAS. Diese ist *essentiell* für -die Teilnahme am Praktikum. Diesmal muss die Abgabe eine ZIP-Datei sein. Die -ZIP-Datei soll die `group.yml` und eine _optionale_ Beschreibung eines eigenen -Systems für MOPS beinhalten. Sie können natürlich auch einfach die -vorgeschlagenen Systeme wählen und müssen keine eigenen Systeme entwerfen. +Die Gruppenverwaltung wird bieten: -== Systeme +* Eine Seite zum erstellen von neuen Gruppen +* Eine Seite zum verwalten von bestehenden Gruppen +* Eine Übersicht über belegte Gruppen +* Detailansicht für Gruppen +* Eine API zum anfragen von Gruppendaten -*Die folgenden Beschreibungen sind keine Spezifikationen, die den Funktionsumfang der Projekte festlegen,* sondern nur ein "Braindump" von den Ideen, die mir zu dem entsprechenden System gekommen sind. Die Beschreibungen sollen Ihnen primär helfen, Systeme auszusuchen, die Sie umsetzen möchten. Wenn Sie einen eigenen Vorschlag für ein System haben, können Sie das auch gerne vorschlagen. Sie müssen dann zusammen mit der `group.yml` Datei einen kurzen Pitch (in etwa wie in diesem Dokument) einreichen, damit wir uns vorstellen können, was Sie machen wollen und den Umfang begutachten. +=== Details -=== Online Modulhandbuch -Im Modulhandbuch werden die Beschreibungen für Veranstaltungen angegeben. Die Beschreibungen werden von den Dozierenden angelegt und werden von einer Verantwortlichen geprüft und dann freigeschaltet. +Über *Gruppen*: -IMPORTANT: Für die automatische Bearbeitung von Klausurzulassungen muss sichergestellt werden, dass Änderungen an den Veranstaltungen nachvollziehbar bleiben. Wenn wir uns zum Beispiel entscheiden, die Veranstaltung "Foobar" in "Barfoo" umzubenennen, aber im Wesentlichen die Veranstaltung dieselbe ist, dann muss in der neuen Veranstaltung die Information erhalten bleiben, dass alle Zulassungen der alten Veranstaltungen in der neuen Veranstaltung gültig bleiben. +* Es gibt private und öffentliche Gruppen +** Privat: Beitritt über Einladungslink +** Öffentlich: Beitritt über Liste +* Jede Gruppe kann einer Veranstalung zugeordnet werden (oder ist eine Veranstaltung) +* Gruppenteilnehmer können Administratorrollen innerhalb der Gruppe einnehmen +* Wenn man eine Gruppe erstellt, wird man dieser direkt hinzugefügt und als Admin registriert (unabhängig davon ob es eine öffentliche oder private Gruppe ist) +* Gruppen verschwinden, wenn sie keine Mitglieder mehr haben -Beschreibungen sollten wie im aktuellen Modulhandbuch strukturiert sein, aber auch zusätzliche Informationen darstellen können. Die einzelnen Informationsblöcke sollen separat befüllt werden und in der REST Schnittstelle (siehe unten) auch separat zugreifbar sein. Es soll _Markdown_ als Textformat für Freitexte verwendet werden. +Über *Admin* (interne Rolle): -Das Modulhandbuch muss als PDF Dokument exportiert werden können. +* Admin's können anderen Gruppenmitgliedern Adminrechte geben +* Admin's können den Beitrittslink für private Guppen erstellen +* Admin's können andere Mitglieder aus der Gruppe entfernen -Für jedes Semester sollen Teile des Handbuchs auswählbar sein, die in dem Semester stattfinden. +Über *Mitglied* (interne Rolle): -Eine HTML Variante des Modulhandbuchs soll zusammen mit der Information, welche Veranstaltungen in welchem Semester stattfinden eine Planungsmöglichkeit für Studierende mit einer Volltext-Such/Filterfunktion liefern. +* Mitglieder haben keine Rechte in der Gruppe. Sie können nur eigenständig aus der Gruppe austreten. -Das Handbuch soll für das Belegungssystem eine REST Schnittstelle anbieten, über die die Veranstaltungs-Stammdaten abgerufen werden können. +Für *Organisatoren* (keycloak Rolle): -=== Belegung -Für ein Semester werden Veranstaltungen ausgesucht, die mit MOPS verwaltet werden sollen. Eine solche Veranstaltung ist von Studierenden innerhalb einer Frist selbständig belegbar. Außerhalb der Frist, sollen Organisatorinnen Studierende hinzufügen können. +* Beliebige Gruppen können erstellt/gelöscht/bearbeitet werden +* Teilnehmerlisten können per .csv importiert werden +* Monitoringfunktionen -Für jede Veranstaltung soll für das entsprechende Semester eine Syllabus Seite erzeugt werden können. Diese Seite besteht aus beliebig vielen Textblöcken, die in Markdown Syntax befüllt werden. Textblöcke aus dem Modulhandbuch sollen eingefügt werden können. +Für *Studenten* (keycloak Rolle) : -Die Syllabus-Seite soll schon vor der Belegung für Studierende lesbar sein. Bei der Belegung wird abgefragt, ob die Voraussetzungen erfüllt sind. Dabei wir der entsprechende Textblock den Studierenden angezeigt und die Studierenden müssen bestätigen, dass sie die Anforderungen erfüllen. Die Anforderungen werden nicht vom System geprüft, da die entsprechenden Daten nicht vorgehalten werden. +* Übersicht mit allen belegten Gruppen +* Übersicht mit allen öffentlichen Gruppen +* Gruppen können erstellt werden +* Öffentlichen Gruppen kann beigetreten werden +* Gruppen, in welchen der Student Admin ist, können verwaltet werden -Das System soll optional Belegung von Übungsgruppen möglich machen. Die Belegung soll mindestens nach folgenden Verfahren möglich sein: +Über die *Schnittstelle*: -* "First come, First serve" mit eigenem Startdatum (d.h. Startdatum unabhängig von der Belegungsfrist) -* Prioritätenverfahren mit Frist +* Alle Gruppen können angefragt werden, zum Datenabgleich +* Eine Liste von Gruppen eines Studenten kann angefragt werden (evtl.) +* Eine einzelne Gruppe kann per ID angefragt werden (evtl.) +* etc? -Das System soll die Belegungsdaten per REST Schnittstelle anbieten. Neben der Belegungsinformation zur Veranstaltung, werden auch die laufenden Daten zur Übungsgruppenbelegung benötigt (auch die Daten beim Prioritätsverfahren vor der Zuteilung damit ggf. Kapazitäten angepasst werden können) +=== Verwendung -=== Gruppenbildung -Diese Anwendung ermöglicht es Studierenden, eigenständig Lerngruppen zu organisieren. Die Lerngruppen sollen dazu dienen Fragen zur Vorlesung oder zu Übungsblättern bei Treffen gemeinsam zu klären. Es soll somit das Finden von Lern- und Abgabepartnerinnen vereinfacht werden. Gruppen sind immer mit einer Veranstaltung verknüpft. Die Organisatorinnen der Veranstaltung haben keinen Zugriff auf die interne Kommunikation, aber erhalten aggregierte statistische Daten über die Gruppen (Teilnehmeranzahl, Anzahl der Interaktionen, ...). - -Studierende können selbstständig Gruppen erstellen. Jede Gruppe hat einen Titel und eine Beschreibung. Gruppen können öffentlich oder privat sein. Öffentliche Gruppen können gesucht (Textsuche und Katalog) werden. Der Beitritt zu einer öffentlichen Gruppe erfolgt eigenständig. Privaten Gruppen kann nur beigetreten werden, wenn ein Beitrittslink bekannt ist. Gruppen können gemeinsame Übungsaufgaben einreichen, vorausgesetzt die Gruppe passt zu den Vorgaben für Abgaben (Größe der Gruppe und alle Teilnehmerinnen sind auch Teilnehmerinnen der Veranstaltung für die eine Abgabe eingereicht werden soll) - -=== Foren -Organisatorinnen sollen für Veranstaltungen beliebig viele Diskussionsforen anlegen können. Für eine Gruppe soll es auch die Möglichkeit geben, ein Forum anzulegen. Ein Forum soll nur für angemeldete Teilnehmerinnen bzw. Gruppenmitglieder lesbar sein. Die Foren sollten sich an den üblichen Implementierungen im Netz orientieren (Bitte nicht unbedingt an der Art, wie Ilias Beiträge organisiert orientieren). Foren sollen entweder anonym sein, oder automatisch die Klarnamen der Teilnehmerinnen verwenden. Es soll die Möglichkeit geben, für Foren einen Moderationsmodus einzuschalten, bei dem alle Beiträge erst durch eine Moderatorin freigeschaltet werden. Teilehmerinnen sollen die Möglichkeit bekommen Benachrichtigungen für ganze Foren oder auch einzelne Diskussionsthreads ein- bzw. auszuschalten. Das System muss eine Volltextsuche bereitstellen (Leseberechtigungen beachten!). - -IMPORTANT: Das Forum muss gegen Sicherheitslücken (z.B. Injection, XSS, ...) abgesichert werden! - - -=== Nachrichtenzentrale - -Die Nachrichtenzentrale dient der Kommunikation zwischen Organisatorinnen (oder -auch anderen Systemen) und Studierenden. Informationen aus den anderen -Teilsystemen (z.B. eine neue Aufgabe oder Korrektur ist verfügbar, eine Frist -läuft ab, neue Materialien wie Aufzeichnung, Übungsblatt, Vorlesungsslides, -...) sollen übersichtlich dargestellt werden. Außerdem sollen Studierende -einstellen können, wie sie bei welchen Nachrichten informiert werden wollen -(z.B. per Mail) und ob die Benachrichtigungen einzeln oder gesammelt als Digest -empfangen werden sollen. - -Es sollte eine Möglichkeit geben Studierende (einzeln, Gruppe, ganze -Veranstaltung, nach anderen Kriterien(?)...) außerplanmäßig über Änderungen zu -informieren. - - -=== Einreichung -Das System soll für Veranstaltungen die Abgabe von Übungsblättern übernehmen. Grundsätzlich besteht eine Abgabe aus einer ZIP-Datei pro Aufgabe eines Übungsblattes. Bei der Einrichtung eines Übungsblattes muss die Abgabestruktur (d.h. die Anzahl der Aufgaben), die Gruppengrößen (in den meisten Fällen 1) und die Abgabefrist festgelegt werden. -Es muss eine Konfigurationsmöglichkeit für die maximale Größe einer Abgabe geben, diese wird global festgelegt. - -Die abgegebenen Dateien werden in einer Instanz von https://min.io/[MinIO] (eine Amazon S3 kompatibler Filestore) abgelegt und die Meta-Informationen (zugehörige Person/Gruppe, Einreichungsdatum, Versionen bestehend aus Originaldateiname und URL im Filestore) werden in einer Datenbank gespeichert. - -Nach Ende der Abgabefrist können Studierende keine Abgaben mehr einreichen. Organisatoren können immer Einreichung anlegen. - -Einzelne Einreichungen können nicht gelöscht werden, auch nicht von Organisatoren. Nach einer gewissen Frist muss es aber möglich sein die Einreichungen (z.B. die Informationen in der DB und die Dateien im Filestore) für einzelne Veranstaltungen vollständig vom Produktionsserver zu löschen. Es muss eine Backup Funktion geben, um die Daten vor der Löschung zu sichern (Es lohnt sich hier, über eine geeignete Struktur im Filestore nachzudenken). - -Das System muss Schnittstellen bereitstellen, über die das Korrektursystem die notwendigen Informationen erhält um die Abgaben zu verteilen. - -Die Benutzeroberfläche für Organisatoren soll die Historie für Einreichungen zugreifbar machen, d.h. nicht nur die letzte Version, sondern auch alle vorher eingereichten Versionen. - -Die Einreichung der Abgaben ist eine der kritischsten Komponenten von MOPS. Insbesondere wollen wir Studierenden die Möglichkeit geben nachzuweisen, dass sie eine Einreichung getätigt haben. Das System soll dazu ein kryptographisches Verfahren verwenden. Pro Datei der Einreichung wird ein sicherer kryptographischer Hashcode berechnet. Die Hashcodes werden zusammen mit dem Einreichdatum vom Server kryptographisch signiert und die so generierte Quittung den Studierenden übergeben. Sollte eine Einreichung verloren gehen, können die Studierenden mit den Originaldateien und der Quittung fälschungssicher nachweisen, dass sie die Einreichung getätigt haben. - -IMPORTANT: Es werden hier selbstverständlich keine eigene Implementierung von kryptographischen Algorithmen verwendet, sondern erprobte Bibliotheken benutzt. - -=== Korrekturverteilung -Das System organisiert die Korrektur der Einreichungen und die Korrekturergebnisse. Es ist nicht die Schnittstelle für Korrektorinnen, sondern dient den Organisatorinnen der Veranstaltung. - -Es sollen Visualisierungen (graphisch, tabellarisch, beides) erzeugt werden, die einen Überblick über den Korrekturstand erlauben: - -* Wieviele Abgaben haben die einzelnen Korrektorinnen? -* Wieviele Abgaben sind schon korrigiert? (nur online) -* Wie ist der aktuelle Stand der Korrektur über alle Korrektorinnen aggregiert? - -Die Informationen über den Korrekturstand müssen von dem System, in dem die Korrekturen vorgenommen werden bezogen werden. - -Die Information über den Gesamtstand kann, falls gewünscht, mit den Studierenden geteilt werden, d.h. es muss eine entsprechende Schnittstelle bereitgestellt werden, die von der Übersichtsseite eingebettet werden kann. - -==== Online Korrekturen -Bei der Online Korrektur handelt es sich um Korrekturen von elektronische eingereichten Dateien (z.B. Programme, Textdateien, ...). Die zu begutachtenden Einreichungen werden vom Einreichungsserver über eine Schnittstelle bereitgestellt. Das Korrektursystem verteilt die Einreichungen auf die Korrektorinnen entsprechend eines spezifizierten Schlüssels (z.B. faire Verteilung nach Arbeitsstunden, es gibt aber auch noch andere Möglichkeiten, z.B. Verteilung auf Übungsgruppenleiter oder faire Verteilung nach Teilaufgabe). - -==== Offline Korrekturen -Bei der Offline Korrektur handelt es sich um Abgaben, die auf Papier getätigt werden. Hier gibt es keine automatische Verteilung, sondern die Korrektorinnen bekommen einen Stapel Abgaben ausgehändigt. Im System wird die Anzahl der Aufgaben pro Blatt festgelegt (Voreinstellung: 1). Im System können, wenn es gewünscht ist, die Anzahlen der Korrekturen pro Korrektorin eingetragen werden um die Visualisierung der Verteilung zu ermöglichen. - -=== Korrekturschnittstelle -Das System ist das Interface, über das Korrektorinnen Zugriff auf die Abgaben erhalten. Die Korrekturen für eine Korrektorin kommen über eine Schnittstelle des Korrekturverteilungssystems. - -==== Online Korrektur -Korrektorinnen können die zugewiesenen Abgaben kommentieren und bewerten. Wichtig ist hier, dass der Umgang mit dem System möglichst effizient sein soll (nicht jede einzelnen Datei einzeln herunterladen, Korrektur auf dem Eigenen Rechner und Batch Upload der Kommentare). Es könnte auch überlegt werden für jede Korrektorin ein git Repository automatisch anzulegen. - -IMPORTANT: Wenn Dateiinhalte im Browser direkt angezeigt werden, muss auf mögliche Sicherheitslücken (Injection, XSS, ...) geachtet werden. - -==== Offline Korrektur -Für manuelle Einreichungen benötigen Korrektorinnen eine Schnittstelle, wo sie die Punkte pro Aufgabe eintragen können. Dazu verwenden sie die Nutzerkennung, die die Studierenden auf die abgabe schreiben müssen. Es werden genauso viele Punktefelder angezeigt, wie im Korrekturverteilungssystem festgelegt wurden. - -=== Punkteübersicht -Das System soll Organisatorinnen eine schnelle (buchstäblich!!!) Übersicht über die Situation im Übungsbetrieb geben. Dazu müssen die aktuellen Punktstände für Studierende angezeigt werden können (inklusive der Informationen, welche Punkte gesichert sind, d.h. wenn Punkte eingetragen, aber die Korrektur noch nicht abgeschlossen ist, sollen diese unsicheren Punkte unterscheidbar dargestellt werden). - -Hier brauchen wir auch Visualisierungen für aggregierte Daten durchschnittliche Punktzahl, Abweichungen, Punkte nach Blättern, Punkte nach Aufgaben etc. Hier sind Darstellungen gefragt, die uns Problem im Übungsbetrieb aufzeigen können gefragt. - -=== Terminfindung und Abstimmung -Um einen gemeinsamen Termin mit mehreren Personen abzustimmen, kann man in diesem System ein Eintrag angelegt werden. Ein Eintrag besteht aus einem Titel, einem Ort, einer optionalen Beschreibung und Vorschlägen für Termine. Die Terminvorschläge sollen sowohl über eine einfach zu bedienende graphische Oberfläche (hier könnte doodle.com oder auch terminplaner.dfn.de als Vorbild genommen werden) eingegeben, als auch über ein Textfile importiert werden können. Es soll auch die Option geben über Fragen abzustimmen. Auch Kommentare sollen abgegeben werden können. - -Terminfindung und Abstimmung können mit einer Gruppe verknüpft werden. Dann können nur Gruppenmitglieder teilnehmen. Alternativ kann der Zugang per Link erfolgen. Jede Person, die den Link kennt, kann dann abstimmen. - -Die Abstimmung kann unter dem Klarnamen oder Pseudonym erfolgen. - -Für alle Terminfindungs- und Abstimmungsprozesse soll ein Datum angegeben werden, an dem die den Prozess betreffenden Daten automatisch gelöscht werden. - -=== Java in der Praxis: Selfservice -Für Veranstaltungen der rheinjug können Kreditpunkte erworben werden. Für je 0.5 CP werden drei normale Abendveranstaltungen oder eine Entwickelbar Veranstaltung besucht und pro Veranstaltung eine kurze Zusammenfassung geschrieben. Die Veranstaltungstermine können über die API von meetup.com abgerufen werden. - -Studierende sollen sich bei dem System für eine kommende Veranstaltung anmelden und nach dem Besuch innerhalb einer Woche die Zusammenfassung einreichen. Die Zusammenfassung wird unter einer CC Lizenz, die Autoren können aussuchen, ob sie namentlich bei einer Veröffentlichung genannt werden wollen oder nicht. - -Die Zusammenfassungen werden von einem Verantwortlichen akzeptiert. Nichtakzeptieren (z.B. weil es inhaltliche Mängel gibt) muss vom System nicht behandelt werden, das erfolgt durch den Verantwortlichen direkt per Mail. - -Studierende, die hinreichend viele Veranstaltungen besucht haben, können diese gegen einen Schein eintauschen. Das System stellt sicher, dass die Bedingungen für die Vergabe erfüllt sind und erzeugt ein PDF, das durch den Verantwortlichen gedruckt und unterschrieben wird. "Verbrauchte" Vorträge können nicht mehrfach benutzt werden und "unverbrauchte" Vorträge bleiben für einen späteren Zeitpunkt erhalten. - -IMPORTANT: Könnte man das vielleicht auch mit kryptographischen Quittungen lösen um die gespeicherten personenbezogenen Daten zu minimieren? Die Texte müssen auf jeden Fall gespeichert werden (inkl. Namen, falls gewünscht) und wir sollten auch Statistische Informationen haben (Wieviele Scheine werden ausgestellt? Wieviele und welche Vorträge werden zusammengefasst? ...). Es ist hier auch daran zu denken dass die Quittungen nur einmal verwendet werden können, d.h., wir müssen auf jeden Fall auch Statusinformationen speichern, die können aber frei von personenbezogenen Daten sein. - -=== Korrektorinnen Bewerbung -In jedem Semester werden studentische Hilfskräfte für den Übungsbetrieb benötigt. In (zumindest) den Grundlagenveranstaltungen wird dazu ein gemeinsames Bewerbungsverfahren benutzt: - -* Bewerber füllen einen Fragebogen aus. -* Nach Ablauf der Frist werden die Bewerberinnen, die potentiell für eine Stelle in Frage kommen gruppiert und den Verantwortlichen der Veranstaltung zur Verfügung gestellt. Bewerberinnen kommen in Frage, wenn sie eine Veranstaltung nicht ausgeschlossen haben. -* Die Verantwortlichen geben für jede Bewerbung eine Priorität an. -* Die Verteilung auf die einzelnen Veranstaltungen werden von einer verantwortlichen Person manuell durchgeführt, dazu wird aber eine hinreichend gute Darstellung der gesammelten Informationen gebraucht -* Am Ende sollen automatisch die Einstellungsbögen für die Personalabteilung als PDF erzeugt werden - -=== Feedback -Das System soll Feedback von Studierenden einsammeln. Als Einheit soll im Folgenden ein einzelner Vorlesungs- oder Übungstermin oder auch eine Aufgabe bezeichnet werden. -Die Feedbackfunktion wird von den Lehrenden für Einheiten aktiviert. Die Aktivierung erfolgt entweder global nach bestimmten Kriterien (z.B. alle Vorlesungen oder alle Aufgaben) oder für einzelne Einheiten. Zu jedem Feedback gibt es einen Zeitraum, in dem das Feedback gesammelt wird. - -Das Feedback soll den Lehrenden angemessen angezeigt werden. Für bestimmtes Feedback (z.B. allgemeine Zufriedenheit) soll auch ein zeitlicher Verlauf dargestellt werden. - -Feedback kann den Studierenden zur Verfügung gestellt werden. Es kann notwendig sein, bestimmte Stellen vorher zu zensieren (z.B. bei beleidigenden Kommentare gegenüber studentischen Hilfskräften, etc.) - -*Besonderheit*: Feedback ist anonym! Es muss hier darauf geachtet werden, dass das Feedback zwar nur von berechtigten Personen kommt (d.h. Studierende müssen auch an der Veranstaltung teilnehmen). Es darf aber nicht nachvollziehbar sein (auch nicht im Logfile), wer ein Feedback abgegeben hat. - -=== Lernportfolios/Lerntagebücher/Lernwiki -Ein Lernportfolio ist eine "Mappe", in der Arbeitsprozesse durch Studierende dokumentiert werden. Außerdem können in einem Portfolio auch Arbeitsergebnisse (Texte, Programmcode, Protokolle, ...) gespeichert werden. Das didaktische Ziel ist die Reflexion über die eigenen Lernprozesse und Entwicklung zu fördern. Es sollte durch die Lehrenden möglich sein, eine Strukturierung oder Beispiele vorzugeben. Portfolios sollten einer Veranstaltung zugeordnet sein und es sollte sowohl Einzel- als auch Gruppenportfolios geben. - -=== Klausurzulassung - -Das System soll für Veranstaltungen die Klausurzulassung verarbeiten und zusammen mit der Anmeldeliste eine Klausurliste erzeugen können. - -MOPS erhält folgende Daten: - -* Eine Liste von Personen, die die Zulassung im Semester erworben haben. Die Liste wird manuell erstellt oder falls die Zulassungskriterien automatisch geprüft werden können automatisch generiert. -* Die Anmeldeliste für eine Klausur. Diese wird von der zuständigen Lehrkraft im Dozierendenportal heruntergeladen und in MOPS hochgeladen. -* Zusätzlich verwaltet MOPS Altzulassungen, die von den Studierenden bis zu einem festgelegten Stichtag eingereicht werden müssen. - -In der Informatik gibt es die Übereinkunft, das Klausurzulassungen bestehen bleiben, wir nennen das eine Altzulassung. Da in den Grundlagenveranstaltungen die Dozierenden wechseln, ist es nicht ganz einfach die Altzulassungen im Blick zu behalten. Ein zentrales System, das die Informationen speichert, ist aus Datenschutzgründen nicht wünschenswert. MOPS soll am Ende des Semesters die Informationen bekommen, welche Studierenden neu zugelassen wurden und für jede dieser Personen eine kryptographisch abgesicherte Quittung erstellen und der Person zukommen lassen. - -Eine solche Quittung beinhaltet in maschinen- und menschenlesbarem Klartext die Information in welchem Semester die Zulassung für welche Veranstaltung erreicht wurde. Die Quittung kann von Studierenden verwendet werden, um eine bestehende Altzulassung nachzuweisen. Dazu reicht die Person die Quittung bei dem System fristgerecht die Quittung ein. Die Quittung wird geprüft, ob sie für die Veranstaltung gültig ist und ob die kryptographische Signatur gültig ist. - -Wenn die Informationen über die Zulassungen zusammengeführt sind, soll für die Lehrenden eine Zulassungsliste ein einem (mit MS Excel/Libre Office) bearbeitbaren Format generiert werden. Die Datei muss bearbeitet werden können, da in der Regel die Studierenden auf verschiedene Hörsäle verteilt werden und für jeden Saal eine eigene Liste gedruckt wird. - -Eine Prüfung einer Quittung muss auch manuell durch eine Organisatorin erfolgen können. Es müssen auch manuell Altzulassungen eingetragen werden können. - -IMPORTANT: Es werden hier selbstverständlich keine eigene Implementierung von kryptographischen Algorithmen verwendet, sondern erprobte Bibliotheken benutzt. - -=== Materialsammlung -Die Materialsammlung soll Dokumente, die von Organisatorinnen für eine Veranstaltung bereitgestellt werden verwalten. Beispiele für Materialien sind Skripte, Übungsblätter, Vorlesungsslides, Videos, Artikel, Links, usw. - -Es wäre gut, wenn die Materialien mit Tags (inhaltlich und organisatorisch) versehen werden, so dass man verschiedene Sichten/Filter auf die Materialien bekommt, z.B. alles zum Thema Git, alle Vorlesungsslides, alles, was als klausurrelevant markiert wurde. Eine Volltextsuche für Standardinhalte (z.B. pdf) oder Metadatensuche (z.B. nach Datum) wäre auch hilfreich. Es sollte auch ein Veröffentlichungsdatum geben, zu dem eine Resource verfügbar ist. - -Es sollte https://min.io/[MinIO] verwendet werden, um die Dateien abzulegen. +Wir werden ein Dockerfile bereitstellen, das heißt ihr könnt die Anwendung einfach starten. +Unter localhost:8081/swagger-ui.html findet ihr die API-Dokumentation. From 46985ccca70aae6ebb59de477c1494ff0cdf3679 Mon Sep 17 00:00:00 2001 From: killerber4t Date: Fri, 13 Mar 2020 16:27:34 +0100 Subject: [PATCH 14/18] add button elements depending on various factors --- .../gruppen2/domain/event/UpdateRoleEvent.java | 8 +++++++- .../gruppen2/service/ControllerService.java | 3 +++ .../resources/templates/detailsMember.html | 18 ++++++++---------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java b/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java index a4301de..570b7e3 100644 --- a/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java @@ -14,8 +14,14 @@ public class UpdateRoleEvent extends Event { Role newRole; public UpdateRoleEvent(Long event_id, Long group_id, String user_id, Role newRole) { - super(event_id, group_id, user_id); + super(event_id,+ group_id, user_id); this.newRole = newRole; } + public UpdateRoleEvent(Long group_id, String user_id, Role newRole) { + super(group_id, user_id); + + this.newRole = newRole; + } + } diff --git a/src/main/java/mops/gruppen2/service/ControllerService.java b/src/main/java/mops/gruppen2/service/ControllerService.java index 75f0b78..c19cf53 100644 --- a/src/main/java/mops/gruppen2/service/ControllerService.java +++ b/src/main/java/mops/gruppen2/service/ControllerService.java @@ -1,6 +1,7 @@ package mops.gruppen2.service; import mops.gruppen2.domain.GroupType; +import mops.gruppen2.domain.Role; import mops.gruppen2.domain.Visibility; import mops.gruppen2.domain.event.*; import mops.gruppen2.security.Account; @@ -20,10 +21,12 @@ public class ControllerService { AddUserEvent addUserEvent = new AddUserEvent(eventService.checkGroup(), account.getName(),account.getGivenname(),account.getFamilyname(),account.getEmail()); UpdateGroupTitleEvent updateGroupTitleEvent = new UpdateGroupTitleEvent(eventService.checkGroup(), account.getName(), title); UpdateGroupDescriptionEvent updateGroupDescriptionEvent = new UpdateGroupDescriptionEvent(eventService.checkGroup(), account.getName(), beschreibung); + UpdateRoleEvent updateRoleEvent = new UpdateRoleEvent(eventService.checkGroup(),account.getName(), Role.ADMIN); eventService.saveEvent(createGroupEvent); eventService.saveEvent(addUserEvent); eventService.saveEvent(updateGroupTitleEvent); eventService.saveEvent(updateGroupDescriptionEvent); + eventService.saveEvent(updateRoleEvent); } } diff --git a/src/main/resources/templates/detailsMember.html b/src/main/resources/templates/detailsMember.html index c912c5a..f6a3827 100644 --- a/src/main/resources/templates/detailsMember.html +++ b/src/main/resources/templates/detailsMember.html @@ -12,10 +12,10 @@