1

Merge remote-tracking branch 'origin/master' into csv-error-handling

# Conflicts:
#	src/main/java/mops/gruppen2/controller/Gruppen2Controller.java
#	src/main/java/mops/gruppen2/domain/User.java
#	src/main/java/mops/gruppen2/service/ControllerService.java
#	src/main/resources/templates/createStudent.html
This commit is contained in:
XXNitram
2020-03-19 17:01:32 +01:00
21 changed files with 185 additions and 48 deletions

View File

@ -8,6 +8,7 @@ import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.GroupNotFoundException;
import mops.gruppen2.domain.exception.WrongFileException;
import mops.gruppen2.domain.exception.NoAdminAfterActionException;
import mops.gruppen2.security.Account;
import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.CsvService;
@ -158,6 +159,21 @@ public class Gruppen2Controller {
return "search";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
@PostMapping("/createGroup")
public String pCreateGroup(KeycloakAuthenticationToken token,
@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam(value = "visibility", required = false) Boolean visibility,
@RequestParam("userMaximum") Long userMaximum) throws EventException {
Account account = keyCloakService.createAccountFromPrincipal(token);
visibility = visibility == null;
controllerService.createGroup(account, title, description, visibility, userMaximum);
return "redirect:/gruppen2/";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
@GetMapping("/details/{id}")
public String showGroupDetails(KeycloakAuthenticationToken token, Model model, @PathVariable("id") Long groupId) throws EventException {
@ -180,12 +196,14 @@ public class Gruppen2Controller {
@PostMapping("/detailsBeitreten")
public String joinGroup(KeycloakAuthenticationToken token, Model model, @RequestParam("id") Long groupId) throws EventException {
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
Group group = userService.getGroupById(groupId);
if (group.getMembers().contains(user)) {
return "error"; //hier soll eigentlich auf die bereits beigetretene Gruppe weitergeleitet werden
}
if (group.getUserMaximum() < group.getMembers().size()) return "error";
controllerService.addUser(account, groupId);
return "redirect:/gruppen2/";
}
@ -195,7 +213,7 @@ public class Gruppen2Controller {
public String showGroupDetailsNoMember(KeycloakAuthenticationToken token, Model model, @RequestParam("id") Long groupId) throws EventException {
model.addAttribute("account", keyCloakService.createAccountFromPrincipal(token));
Group group = userService.getGroupById(groupId);
if (group != null) {
if (group != null && group.getUserMaximum() > group.getMembers().size()) {
model.addAttribute("group", group);
return "detailsNoMember";
}
@ -219,6 +237,7 @@ public class Gruppen2Controller {
public String pLeaveGroup(KeycloakAuthenticationToken token, @RequestParam("group_id") Long groupId) throws EventException {
Account account = keyCloakService.createAccountFromPrincipal(token);
User user = new User(account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
controllerService.passIfLastAdmin(account, groupId);
controllerService.deleteUser(user.getId(), groupId);
return "redirect:/gruppen2/";
}
@ -243,6 +262,16 @@ public class Gruppen2Controller {
@PostMapping("/details/members/changeRole")
public String changeRole(KeycloakAuthenticationToken token, @RequestParam("group_id") Long groupId,
@RequestParam("user_id") String userId) throws EventException {
Account account = keyCloakService.createAccountFromPrincipal(token);
if (userId.equals(account.getName())) {
if (controllerService.passIfLastAdmin(account, groupId)){
throw new NoAdminAfterActionException("Du otto bist letzter Admin");
}
controllerService.updateRole(userId, groupId);
return "redirect:/gruppen2/details/" + groupId;
}
controllerService.updateRole(userId, groupId);
return "redirect:/gruppen2/details/members/" + groupId;
}

View File

@ -20,6 +20,7 @@ public class Group {
private Long id;
private String title;
private String description;
private Long userMaximum;
private GroupType type;
private Visibility visibility;
private Long parent;

View File

@ -7,6 +7,7 @@ import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.GroupFullException;
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
/**
@ -35,6 +36,10 @@ public class AddUserEvent extends Event {
if (group.getMembers().contains(user)) {
throw new UserAlreadyExistsException(this.getClass().toString());
}
//andere exception
if (group.getMembers().size() == group.getUserMaximum()){
throw new GroupFullException(this.getClass().toString());
}
group.getMembers().add(user);
group.getRoles().put(userId, Role.MEMBER);

View File

@ -15,12 +15,14 @@ public class CreateGroupEvent extends Event {
private Visibility groupVisibility;
private Long groupParent;
private GroupType groupType;
private Long groupUserMaximum;
public CreateGroupEvent(Long groupId, String userId, Long parent, GroupType type, Visibility visibility) {
public CreateGroupEvent(Long groupId, String userId, Long parent, GroupType type, Visibility visibility, Long userMaximum) {
super(groupId, userId);
this.groupParent = parent;
this.groupType = type;
this.groupVisibility = visibility;
this.groupUserMaximum = userMaximum;
}
@Override
@ -29,5 +31,6 @@ public class CreateGroupEvent extends Event {
group.setParent(this.groupParent);
group.setType(this.groupType);
group.setVisibility(this.groupVisibility);
group.setUserMaximum(this.groupUserMaximum);
}
}

View File

@ -0,0 +1,11 @@
package mops.gruppen2.domain.exception;
import org.springframework.http.HttpStatus;
public class GroupFullException extends EventException {
public GroupFullException(String info) {
super(HttpStatus.INTERNAL_SERVER_ERROR, "Der User existiert bereits.", info);
}
}

View File

@ -0,0 +1,10 @@
package mops.gruppen2.domain.exception;
import org.springframework.http.HttpStatus;
public class NoAdminAfterActionException extends EventException {
public NoAdminAfterActionException(String info) {
super(HttpStatus.INTERNAL_SERVER_ERROR, "Nach dieser Aktion hätte die Gruppe keinen Admin mehr", info);
}
}

View File

@ -18,8 +18,11 @@ import mops.gruppen2.security.Account;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static mops.gruppen2.domain.Role.ADMIN;
@Service
public class ControllerService {
@ -43,7 +46,7 @@ public class ControllerService {
* @param title Gruppentitel
* @param description Gruppenbeschreibung
*/
public void createGroup(Account account, String title, String description, Boolean visibility) throws EventException {
public void createGroup(Account account, String title, String description, Boolean visibility, Long userMaximum) throws EventException {
Visibility visibility1;
Long groupId = eventService.checkGroup();
@ -54,7 +57,7 @@ public class ControllerService {
createInviteLink(groupId);
}
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), null, GroupType.SIMPLE, visibility1);
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), null, GroupType.SIMPLE, visibility1, userMaximum);
eventService.saveEvent(createGroupEvent);
addUser(account, groupId);
@ -130,10 +133,10 @@ public class ControllerService {
throw new UserNotFoundException(this.getClass().toString());
}
if (group.getRoles().get(user.getId()) == Role.ADMIN) {
if (group.getRoles().get(user.getId()) == ADMIN) {
updateRoleEvent = new UpdateRoleEvent(groupId, user.getId(), Role.MEMBER);
} else {
updateRoleEvent = new UpdateRoleEvent(groupId, user.getId(), Role.ADMIN);
updateRoleEvent = new UpdateRoleEvent(groupId, user.getId(), ADMIN);
}
eventService.saveEvent(updateRoleEvent);
}
@ -160,4 +163,56 @@ public class ControllerService {
eventService.saveEvent(deleteGroupEvent);
}
public void createLecture(Account account, String title, String description, Boolean visibility, List<User> users) throws EventException {
Visibility visibility1;
Long groupId = eventService.checkGroup();
if (visibility) {
visibility1 = Visibility.PUBLIC;
} else {
visibility1 = Visibility.PRIVATE;
}
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), null, GroupType.LECTURE, visibility1, 1000L); //this has to be changed also Usermaximum
eventService.saveEvent(createGroupEvent);
addUser(account, groupId);
updateTitle(account, groupId, title);
updateDescription(account, groupId, description);
updateRole(account.getName(), groupId);
addUserList(users, groupId);
}
public boolean passIfLastAdmin(Account account, Long groupId){
Group group = userService.getGroupById(groupId);
if (group.getMembers().size() <= 1){
return true;
}
if (isLastAdmin(account, group)){
String newAdminId = getVeteranMember(account, group);
updateRole(newAdminId, groupId);
}
return false;
}
private boolean isLastAdmin(Account account, Group group){
for (Map.Entry<String, Role> entry : group.getRoles().entrySet()){
if (entry.getValue().equals(ADMIN)){
if (!(entry.getKey().equals(account.getName()))){
return false;
}
}
}
return true;
}
private String getVeteranMember(Account account, Group group){
List<User> mitglieder = group.getMembers();
if (mitglieder.get(0).getId().equals(account.getName())){
return mitglieder.get(1).getId();
}
return mitglieder.get(0).getId();
}
}

View File

@ -1,6 +1,7 @@
package mops.gruppen2.service;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.dto.EventDTO;
import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.exception.EventException;
@ -66,11 +67,11 @@ public class GroupService {
return groups.get(groupId);
}
private List<Long> removeUserGroups(List<Long> groupIds, List<Long> userGroups) {
for (Long groupId : userGroups) {
groupIds.remove(groupId);
private List<Group> removeUserGroups(List<Group> visibleGroups, List<Group> userGroups) {
for (Group group : userGroups) {
visibleGroups.remove(group);
}
return groupIds;
return visibleGroups;
}
/**
@ -81,10 +82,18 @@ public class GroupService {
* @throws EventException Projektionsfehler
*/
public List<Group> getAllGroupWithVisibilityPublic(String userId) throws EventException {
List<Long> groupIds = removeUserGroups(eventRepository.findGroup_idsWhereVisibility(Boolean.TRUE), eventRepository.findGroup_idsWhereUser_id(userId));
List<EventDTO> eventDTOS = eventRepository.findAllEventsOfGroups(groupIds);
List<Event> events = eventService.translateEventDTOs(eventDTOS);
return projectEventList(events);
User user = new User(userId,null, null, null);
List<Event> eventsVisible = eventService.translateEventDTOs(eventRepository.findAllEventsOfGroups(eventRepository.findGroup_idsWhereVisibility(Boolean.TRUE)));
List<Group> visibleGroups = projectEventList(eventsVisible);
List<Event> eventsUser = getGroupEvents(eventRepository.findGroup_idsWhereUser_id(userId));
List<Group> groups = projectEventList(eventsUser);
List<Group> newGroups = new ArrayList<>();
for (Group group : groups) {
if (group.getMembers().contains(user)) {
newGroups.add(group);
}
}
return removeUserGroups(visibleGroups, newGroups);
}

View File

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

View File

@ -33,18 +33,23 @@
<div class="row">
<div class="col-10">
<h1>Gruppenerstellung</h1>
<form method="post" action="/gruppen2/createStudent">
<div class="shadow p-2"
style=" border: 10px solid aliceblue; background: aliceblue">
<form method="post" action="/gruppen2/createGroup">
<div class="shadow p-2" style=" border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
<div class="form-group">
<label for="titel">Titel</label>
<input class="form-control" id="titel" required th:name="title"
type="text">
</div>
<div class="form-group">
<label for="beschreibung">Beschreibung</label>
<textarea class="form-control" id="beschreibung" required
rows="3" th:name="beschreibung"></textarea>
<label for="description">Beschreibung</label>
<textarea class="form-control" id="description" required
rows="3" th:name="description"></textarea>
</div>
<div class="form-group mt-3">
<label for="userMaximum">Teilnehmeranzahl</label>
<input class="form-control" id="userMaximum" required th:name="userMaximum"
type="number" min="1">
</div>
<div class="custom-control custom-checkbox">
<input class="custom-control-input" id="visibility" th:name="visibility"

View File

@ -31,8 +31,7 @@
<main th:fragment="bodycontent">
<div class="container-fluid">
<div class="row">
<div class="col-9 shadow-sm p-4"
style="border: 10px solid aliceblue; background: aliceblue">
<div class="col-9 shadow-sm p-4" style="border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
<h3>
<span class="badge badge-pill badge-dark" style="background: darkslategray"
@ -63,13 +62,18 @@
<div class="col-3" style="white-space: nowrap">
<div style="display: inline-block; margin: 0">
<h2>Mitglieder</h2>
<div>
<h4>
<a th:text="${group.getMembers().size()}"></a>
<a>von maximal</a>
<a th:text="${group.getUserMaximum()}"></a>
<a>Benutzern.</a>
</h4>
</div>
<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: right">
Mitglieder bearbeiten
</button>
<button class="btn btn-secondary" style="background: slategrey; float: left">Mitglieder bearbeiten</button>
</form>
</div>
<br>

View File

@ -31,8 +31,7 @@
<div class="container-fluid">
<div class="row">
<div class="col-9">
<div class="shadow-sm p-4"
style="border: 10px solid aliceblue; background: aliceblue">
<div class="shadow-sm p-4" style="border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
<h3>
<span class="badge badge-pill badge-dark" style="background: darkslategray"

View File

@ -66,11 +66,10 @@
<tr>
<th scope="col">Mitglied</th>
<th scope="col" style="width: 180px">Rolle</th>
<th scope="col" style="width: 270px">Optionen</th>
<th scope="col" >Optionen</th>
</tr>
</thead>
<tbody class="table-striped">
<tr th:each="member : ${group.getMembers()}">
<th th:text="${member.getId()}"></th>
<td>
@ -92,17 +91,16 @@
type="hidden">
<input th:name="user_id" th:value="${member.getId()}"
type="hidden">
<button class="btn btn-danger btn-sm">Mitglied entfernen
<button th:if='${member.getId() != account.getName()}' class="btn btn-danger btn-sm">Mitglied entfernen
</button>
</form>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" style="background: #52a1eb; border-style: none"
type="button">
<a th:href="@{/gruppen2/details(id=${group.getId()})}" style="color: white">Fertig</a>
</button>
<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>
</form>
</div>
</div>
</div>

View File

@ -10,7 +10,7 @@
<title>Seite nicht gefunden</title>
</head>
<body>
<div class="mx-auto" style="vertical-align: center; horiz-align: center; top: 50%; left: 50%;">
<div class="mx-auto" style="vertical-align: border-radius: 5px; center; horiz-align: center; top: 50%; left: 50%;">
<div class="jumbotron" style="background: aliceblue">
<div class="container">
<h1 class="display-3">UPSI</h1>

View File

@ -44,7 +44,7 @@
</h3>
<br>
<div th:each="gruppe: ${gruppen}">
<div class="shadow-sm p-4" style="border: none; background: aliceblue">
<div class="shadow-sm p-4" style="border: none; border-radius: 5px; background: aliceblue">
<h3 style="color: dodgerblue; font-weight: bold;">
<a th:href="@{/gruppen2/details/{id}(id=${gruppe.getId()})}"
th:text="${gruppe.getTitle()}"></a>

View File

@ -33,7 +33,7 @@
<div class="col-10">
<h1>Gruppensuche</h1>
<form action="/gruppen2/findGroup" method="get">
<div class="shadow" style="border: 10px solid aliceblue; background: aliceblue">
<div class="shadow" style="border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
<div class="form-group">
<label for="suchleiste">Suchbegriff:</label>
<input class="form-control" id="suchleiste"

View File

@ -56,7 +56,8 @@ public class EventBuilder {
faker.random().hex(),
null,
GroupType.SIMPLE,
Visibility.PRIVATE
Visibility.PRIVATE,
null
);
}

View File

@ -16,6 +16,7 @@ class AddUserEventTest {
Group group = new Group();
User user = new User("user1", "Stein", "Speck", "@sdasd");
group.getMembers().add(user);
group.setUserMaximum(10L);
Event event1 = new AddUserEvent(4L, "user2", "Rock", "Roll", "and");
event1.apply(group);

View File

@ -56,7 +56,7 @@ class EventServiceTest {
@Test
void getDTOOffentlichTest() {
CreateGroupEvent createGroupEvent = new CreateGroupEvent(eventService.checkGroup(), "test", null, GroupType.LECTURE, Visibility.PUBLIC);
CreateGroupEvent createGroupEvent = new CreateGroupEvent(eventService.checkGroup(), "test", null, GroupType.LECTURE, Visibility.PUBLIC, null);
EventDTO eventDTO = eventService.getDTO(createGroupEvent);
assertTrue(eventDTO.isVisibility());
}

View File

@ -27,9 +27,9 @@ class GroupServiceTest {
@Test
void rightClassForSuccessfulGroup() throws Exception {
void rightClassForSuccessfulGroup() {
List<Event> eventList = new ArrayList<>();
eventList.add(new CreateGroupEvent(1L, "Prof", null, GroupType.LECTURE, Visibility.PRIVATE));
eventList.add(new CreateGroupEvent(1L, "Prof", null, GroupType.LECTURE, Visibility.PRIVATE,1000L));
eventList.add(new AddUserEvent(1L, "Ulli", "Ulli", "Honnis", "FC@B.de"));
List<Group> groups = groupService.projectEventList(eventList);