1

initial group log

This commit is contained in:
Christoph
2020-04-17 14:55:43 +02:00
parent 8097cbfaf3
commit 0bb0b4594f
21 changed files with 147 additions and 11 deletions

View File

@ -22,10 +22,10 @@ public class KeycloakConfig {
@Value("${keycloak.resource}") @Value("${keycloak.resource}")
private String clientId; private String clientId;
@Value("9f8d3616-60d3-48ea-9d14-06ae9eeee5cb") @Value("2e2e5770-c454-4d31-be99-9d8c34c93089")
private String clientSecret; private String clientSecret;
@Value("https://gruppenkeycloak.herokuapp.com/auth/realms/Gruppen/protocol/openid-connect/token") @Value("https://churl-keycloak.herokuapp.com/auth/realms/Gruppen/protocol/openid-connect/token")
private String tokenUri; private String tokenUri;
@Bean @Bean

View File

@ -45,6 +45,11 @@ public class AddMemberEvent extends Event {
log.trace("\t\t\t\t\tNeue Members: {}", group.getMembers()); log.trace("\t\t\t\t\tNeue Members: {}", group.getMembers());
} }
@Override
public String format() {
return "Benutzer hinzugefügt: " + target + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.ADDMEMBER.toString(); return EventType.ADDMEMBER.toString();

View File

@ -39,6 +39,11 @@ public class CreateGroupEvent extends Event {
log.trace("\t\t\t\t\tNeue Gruppe: {}", group.toString()); log.trace("\t\t\t\t\tNeue Gruppe: {}", group.toString());
} }
@Override
public String format() {
return "Gruppe erstellt.";
}
@Override @Override
public String type() { public String type() {
return EventType.CREATEGROUP.toString(); return EventType.CREATEGROUP.toString();

View File

@ -30,6 +30,11 @@ public class DestroyGroupEvent extends Event {
log.trace("\t\t\t\t\tGelöschte Gruppe: {}", group.toString()); log.trace("\t\t\t\t\tGelöschte Gruppe: {}", group.toString());
} }
@Override
public String format() {
return "Gruppe gelöscht.";
}
@Override @Override
public String type() { public String type() {
return EventType.DESTROYGROUP.toString(); return EventType.DESTROYGROUP.toString();

View File

@ -13,6 +13,7 @@ import mops.gruppen2.domain.exception.IdMismatchException;
import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.Group;
import mops.gruppen2.infrastructure.GroupCache; import mops.gruppen2.infrastructure.GroupCache;
import java.time.LocalDateTime;
import java.util.UUID; import java.util.UUID;
@Log4j2 @Log4j2
@ -44,6 +45,9 @@ public abstract class Event {
@JsonProperty("target") @JsonProperty("target")
protected String target; protected String target;
@JsonProperty("date")
protected LocalDateTime date;
public Event(UUID groupid, String exec, String target) { public Event(UUID groupid, String exec, String target) {
this.groupid = groupid; this.groupid = groupid;
this.exec = exec; this.exec = exec;
@ -54,6 +58,7 @@ public abstract class Event {
if (this.version != 0) { if (this.version != 0) {
throw new BadArgumentException("Event wurde schon initialisiert. (" + type() + ")"); throw new BadArgumentException("Event wurde schon initialisiert. (" + type() + ")");
} }
date = LocalDateTime.now();
log.trace("Event wurde initialisiert. (" + type() + "," + version + ")"); log.trace("Event wurde initialisiert. (" + type() + "," + version + ")");
@ -88,6 +93,8 @@ public abstract class Event {
protected abstract void applyEvent(Group group) throws EventException; protected abstract void applyEvent(Group group) throws EventException;
public abstract String format();
@JsonIgnore @JsonIgnore
public abstract String type(); public abstract String type();
} }

View File

@ -34,6 +34,11 @@ public class KickMemberEvent extends Event {
log.trace("\t\t\t\t\tNeue Members: {}", group.getMembers()); log.trace("\t\t\t\t\tNeue Members: {}", group.getMembers());
} }
@Override
public String format() {
return "Mitglied entfernt: " + target + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.KICKMEMBER.toString(); return EventType.KICKMEMBER.toString();

View File

@ -38,6 +38,11 @@ public class SetDescriptionEvent extends Event {
log.trace("\t\t\t\t\tNeue Beschreibung: {}", group.getDescription()); log.trace("\t\t\t\t\tNeue Beschreibung: {}", group.getDescription());
} }
@Override
public String format() {
return "Beschreibung gesetzt: " + description + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.SETDESCRIPTION.toString(); return EventType.SETDESCRIPTION.toString();

View File

@ -38,6 +38,11 @@ public class SetInviteLinkEvent extends Event {
log.trace("\t\t\t\t\tNeuer Link: {}", group.getLink()); log.trace("\t\t\t\t\tNeuer Link: {}", group.getLink());
} }
@Override
public String format() {
return "Einladungslink gesetzt: " + link + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.SETLINK.toString(); return EventType.SETLINK.toString();

View File

@ -36,6 +36,11 @@ public class SetLimitEvent extends Event {
log.trace("\t\t\t\t\tNeues UserLimit: {}", group.getLimit()); log.trace("\t\t\t\t\tNeues UserLimit: {}", group.getLimit());
} }
@Override
public String format() {
return "Benutzerlimit gesetzt: " + limit + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.SETLIMIT.toString(); return EventType.SETLIMIT.toString();

View File

@ -35,6 +35,11 @@ public class SetParentEvent extends Event {
log.trace("\t\t\t\t\tNeues Parent: {}", group.getParent()); log.trace("\t\t\t\t\tNeues Parent: {}", group.getParent());
} }
@Override
public String format() {
return "Veranstaltungszugehörigkeit gesetzt: " + parent.getValue() + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.SETPARENT.toString(); return EventType.SETPARENT.toString();

View File

@ -38,6 +38,11 @@ public class SetTitleEvent extends Event {
log.trace("\t\t\t\t\tNeuer Titel: {}", group.getTitle()); log.trace("\t\t\t\t\tNeuer Titel: {}", group.getTitle());
} }
@Override
public String format() {
return "Titel gesetzt: " + title + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.SETTITLE.toString(); return EventType.SETTITLE.toString();

View File

@ -37,6 +37,11 @@ public class SetTypeEvent extends Event {
group.setType(exec, type); group.setType(exec, type);
} }
@Override
public String format() {
return "Gruppentype gesetzt: " + type + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.SETTYPE.toString(); return EventType.SETTYPE.toString();

View File

@ -38,6 +38,11 @@ public class UpdateRoleEvent extends Event {
log.trace("\t\t\t\t\tNeue Admin: {}", group.getAdmins()); log.trace("\t\t\t\t\tNeue Admin: {}", group.getAdmins());
} }
@Override
public String format() {
return "Mitgliedsrolle gesetzt: " + target + ": " + role + ".";
}
@Override @Override
public String type() { public String type() {
return EventType.UPDATEROLE.toString(); return EventType.UPDATEROLE.toString();

View File

@ -10,6 +10,7 @@ import mops.gruppen2.persistance.EventRepository;
import mops.gruppen2.persistance.dto.EventDTO; import mops.gruppen2.persistance.dto.EventDTO;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -59,7 +60,8 @@ public class EventStoreService {
event.getExec(), event.getExec(),
event.getTarget(), event.getTarget(),
event.type(), event.type(),
payload); payload,
Timestamp.valueOf(event.getDate()));
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Event ({}) konnte nicht serialisiert werden!", event, e); log.error("Event ({}) konnte nicht serialisiert werden!", event, e);
throw new BadPayloadException(EventStoreService.class.toString()); throw new BadPayloadException(EventStoreService.class.toString());
@ -95,4 +97,8 @@ public class EventStoreService {
public List<Event> findAllEvents() { public List<Event> findAllEvents() {
return getEventsFromDTOs(eventStore.findAllEvents()); return getEventsFromDTOs(eventStore.findAllEvents());
} }
public List<Event> findGroupEvents(String groupId) {
return getEventsFromDTOs(eventStore.findGroupEvents(groupId));
}
} }

View File

@ -8,6 +8,7 @@ import mops.gruppen2.domain.model.group.User;
import mops.gruppen2.domain.model.group.wrapper.Description; import mops.gruppen2.domain.model.group.wrapper.Description;
import mops.gruppen2.domain.model.group.wrapper.Limit; import mops.gruppen2.domain.model.group.wrapper.Limit;
import mops.gruppen2.domain.model.group.wrapper.Title; import mops.gruppen2.domain.model.group.wrapper.Title;
import mops.gruppen2.domain.service.EventStoreService;
import mops.gruppen2.domain.service.GroupService; import mops.gruppen2.domain.service.GroupService;
import mops.gruppen2.domain.service.helper.CsvHelper; import mops.gruppen2.domain.service.helper.CsvHelper;
import mops.gruppen2.domain.service.helper.ValidationHelper; import mops.gruppen2.domain.service.helper.ValidationHelper;
@ -37,6 +38,7 @@ public class GroupDetailsController {
private final GroupCache groupCache; private final GroupCache groupCache;
private final GroupService groupService; private final GroupService groupService;
private final EventStoreService eventStoreService;
@RolesAllowed({"ROLE_orga", "ROLE_studentin"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin"})
@GetMapping("/details/{id}") @GetMapping("/details/{id}")
@ -94,6 +96,17 @@ public class GroupDetailsController {
return "redirect:/gruppen2"; return "redirect:/gruppen2";
} }
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
@GetMapping("details/{id}/history")
public String getDetailsHistory(KeycloakAuthenticationToken token,
Model model,
@PathVariable("id") String groupId) {
model.addAttribute("events", eventStoreService.findGroupEvents(groupId));
return "history";
}
@RolesAllowed({"ROLE_orga", "ROLE_studentin"}) @RolesAllowed({"ROLE_orga", "ROLE_studentin"})
@GetMapping("/details/{id}/edit") @GetMapping("/details/{id}/edit")
public String getDetailsEdit(KeycloakAuthenticationToken token, public String getDetailsEdit(KeycloakAuthenticationToken token,
@ -127,8 +140,6 @@ public class GroupDetailsController {
String principal = token.getName(); String principal = token.getName();
Group group = groupCache.group(UUID.fromString(groupId)); Group group = groupCache.group(UUID.fromString(groupId));
System.out.println(group);
groupService.setTitle(group, principal, title); groupService.setTitle(group, principal, title);
groupService.setDescription(group, principal, description); groupService.setDescription(group, principal, description);

View File

@ -3,6 +3,7 @@ package mops.gruppen2.persistance;
import mops.gruppen2.persistance.dto.EventDTO; import mops.gruppen2.persistance.dto.EventDTO;
import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
@ -16,4 +17,7 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
@Query("SELECT * FROM event") @Query("SELECT * FROM event")
List<EventDTO> findAllEvents(); List<EventDTO> findAllEvents();
@Query("SELECT * FROM event WHERE group_id = :groupid")
List<EventDTO> findGroupEvents(@Param("groupid") String groupId);
} }

View File

@ -5,6 +5,8 @@ import lombok.Getter;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.relational.core.mapping.Table;
import java.sql.Timestamp;
@Table("event") @Table("event")
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@ -21,4 +23,6 @@ public class EventDTO {
String event_type; String event_type;
String event_payload; String event_payload;
Timestamp timestamp;
} }

View File

@ -11,12 +11,12 @@ spring.profiles.active = dev
#keycloak.use-resource-role-mappings = true #keycloak.use-resource-role-mappings = true
#keycloak.autodetect-bearer-only = true #keycloak.autodetect-bearer-only = true
#keycloak.confidential-port = 443 #keycloak.confidential-port = 443
keycloak.auth-server-url = https://gruppenkeycloak.herokuapp.com/auth keycloak.auth-server-url = https://churl-keycloak.herokuapp.com/auth
hhu_keycloak.token-uri = https://gruppenkeycloak.herokuapp.com/auth/realms/Gruppen/protocol/openid-connect/token hhu_keycloak.token-uri = https://churl-keycloak.herokuapp.com/auth/realms/gruppen/protocol/openid-connect/token
keycloak.principal-attribute = preferred_username keycloak.principal-attribute = preferred_username
keycloak.realm = Gruppen keycloak.realm = gruppen
keycloak.resource = gruppen-app keycloak.resource = gruppen-app
keycloak.credentials.secret = 9f8d3616-60d3-48ea-9d14-06ae9eeee5cb keycloak.credentials.secret = 2e2e5770-c454-4d31-be99-9d8c34c93089
keycloak.verify-token-audience = true keycloak.verify-token-audience = true
keycloak.use-resource-role-mappings = true keycloak.use-resource-role-mappings = true
keycloak.autodetect-bearer-only = true keycloak.autodetect-bearer-only = true

View File

@ -8,5 +8,6 @@ CREATE TABLE event
exec_id VARCHAR(50) NOT NULL, exec_id VARCHAR(50) NOT NULL,
target_id VARCHAR(50), target_id VARCHAR(50),
event_type VARCHAR(32) NOT NULL, event_type VARCHAR(32) NOT NULL,
timestamp DATETIME NOT NULL,
event_payload VARCHAR(2500) NOT NULL event_payload VARCHAR(2500) NOT NULL
); );

View File

@ -36,8 +36,7 @@
</div> </div>
<input class="form-control" id="linkview" readonly th:value="${link}" type="text"> <input class="form-control" id="linkview" readonly th:value="${link}" type="text">
<div class="input-group-append"> <div class="input-group-append">
<button type="button" class="btn btn-secondary" <button type="button" class="btn btn-secondary" onclick="copyLink()">Link kopieren
onclick="copyLink()">Link kopieren
</button> </button>
</div> </div>
</div> </div>
@ -89,6 +88,18 @@
</div> </div>
</div> </div>
<div class="content">
<div class="content-heading">
<span>Event-Historie</span>
</div>
<div class="row">
<!--Spacer-->
<span class="col"></span>
<a class="btn btn-primary btn-bar" th:href="@{/gruppen2/details/{id}/history(id=${group.getId()})}">Event-Log</a>
</div>
</div>
<!--Teilnehmerliste--> <!--Teilnehmerliste-->
<div class="content members"> <div class="content members">
<div class="content-heading"> <div class="content-heading">

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="de" xmlns:th="http://www.thymeleaf.org" th:replace="~{mopslayout :: html(
name='Gruppenfindung',
title='Event-Log',
headcontent=~{fragments/general :: headcontent('none')},
navigation=~{fragments/general :: nav('none')},
bodycontent=~{:: bodycontent})}">
<body>
<main th:fragment="bodycontent">
<div class="container-fluid">
<h1 class="def-cursor">Event-Log</h1>
<div class="content" th:each="event : ${events}">
<div class="content-heading row">
<span th:text="${event.type()}"></span>
<span class="col"></span>
<span>Datum: </span>
<span th:text="${event.getDate()}"></span>
</div>
<div class="content-text-in">
<span th:text="${'User:' + event.getExec()}"></span>
<span th:text="${'>>>' + event.format()}"></span>
</div>
</div>
</div>
</main>
</body>
</html>