Merge branch 'csrf' into invite-link-update
# Conflicts: # src/main/java/mops/gruppen2/service/ControllerService.java # src/main/resources/schema.sql
This commit is contained in:
@ -54,6 +54,7 @@ public class WebController {
|
||||
* @param model tolles model
|
||||
* @return index.html
|
||||
*/
|
||||
|
||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
|
||||
@GetMapping("")
|
||||
public String index(KeycloakAuthenticationToken token, Model model) throws EventException {
|
||||
@ -67,7 +68,7 @@ public class WebController {
|
||||
|
||||
@RolesAllowed({"ROLE_orga", "ROLE_actuator)"})
|
||||
@GetMapping("/createOrga")
|
||||
public String createOrga(KeycloakAuthenticationToken token, Model model) {
|
||||
public String createGroupAsOrga(KeycloakAuthenticationToken token, Model model) {
|
||||
Account account = keyCloakService.createAccountFromPrincipal(token);
|
||||
model.addAttribute("account", account);
|
||||
model.addAttribute("lectures", groupService.getAllLecturesWithVisibilityPublic());
|
||||
@ -76,29 +77,28 @@ public class WebController {
|
||||
|
||||
@RolesAllowed({"ROLE_orga", "ROLE_actuator)"})
|
||||
@PostMapping("/createOrga")
|
||||
public String pCreateOrga(KeycloakAuthenticationToken token,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("description") String description,
|
||||
@RequestParam(value = "visibility", required = false) Boolean visibility,
|
||||
@RequestParam(value = "lecture", required = false) Boolean lecture,
|
||||
@RequestParam("userMaximum") Long userMaximum,
|
||||
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
|
||||
@RequestParam(value = "parent", required = false) String parent,
|
||||
@RequestParam(value = "file", required = false) MultipartFile file) throws IOException, EventException {
|
||||
public String postCrateGroupAsOrga(KeycloakAuthenticationToken token,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("description") String description,
|
||||
@RequestParam(value = "visibility", required = false) Boolean visibility,
|
||||
@RequestParam(value = "lecture", required = false) Boolean lecture,
|
||||
@RequestParam("userMaximum") Long userMaximum,
|
||||
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
|
||||
@RequestParam(value = "parent", required = false) String parent,
|
||||
@RequestParam(value = "file", required = false) MultipartFile file) throws IOException, EventException {
|
||||
|
||||
Account account = keyCloakService.createAccountFromPrincipal(token);
|
||||
UUID parentUUID = controllerService.getUUID(parent);
|
||||
List<User> userList = new ArrayList<>();
|
||||
|
||||
validationService.checkFields(description, title, userMaximum, maxInfiniteUsers);
|
||||
Group group = userService.getGroupById(controllerService.createOrga(account, title, description, visibility, lecture, maxInfiniteUsers, userMaximum, parentUUID));
|
||||
userList = validationService.checkFile(file, userList, group.getId().toString(), group, account);
|
||||
controllerService.addUserList(userList, group.getId());
|
||||
controllerService.createGroupAsOrga(account, title, description, visibility, lecture, maxInfiniteUsers, userMaximum, parentUUID, file);
|
||||
|
||||
return "redirect:/gruppen2/";
|
||||
}
|
||||
|
||||
@RolesAllowed({"ROLE_studentin"})
|
||||
@GetMapping("/createStudent")
|
||||
public String createStudent(KeycloakAuthenticationToken token, Model model) {
|
||||
public String createGroupAsStudent(KeycloakAuthenticationToken token, Model model) {
|
||||
Account account = keyCloakService.createAccountFromPrincipal(token);
|
||||
model.addAttribute("account", account);
|
||||
model.addAttribute("lectures", groupService.getAllLecturesWithVisibilityPublic());
|
||||
@ -107,18 +107,18 @@ public class WebController {
|
||||
|
||||
@RolesAllowed({"ROLE_studentin"})
|
||||
@PostMapping("/createStudent")
|
||||
public String pCreateStudent(KeycloakAuthenticationToken token,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("description") String description,
|
||||
@RequestParam(value = "visibility", required = false) Boolean visibility,
|
||||
@RequestParam("userMaximum") Long userMaximum,
|
||||
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
|
||||
@RequestParam(value = "parent", required = false) String parent) throws EventException {
|
||||
public String postCreateGroupAsStudent(KeycloakAuthenticationToken token,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("description") String description,
|
||||
@RequestParam(value = "visibility", required = false) Boolean visibility,
|
||||
@RequestParam("userMaximum") Long userMaximum,
|
||||
@RequestParam(value = "maxInfiniteUsers", required = false) Boolean maxInfiniteUsers,
|
||||
@RequestParam(value = "parent", required = false) String parent) throws EventException {
|
||||
|
||||
Account account = keyCloakService.createAccountFromPrincipal(token);
|
||||
UUID parentUUID = controllerService.getUUID(parent);
|
||||
validationService.checkFields(description, title, userMaximum, maxInfiniteUsers);
|
||||
controllerService.createGroup(account, title, description, visibility, maxInfiniteUsers, userMaximum, parentUUID);
|
||||
controllerService.createGroup(account, title, description, visibility, null, maxInfiniteUsers, userMaximum, parentUUID);
|
||||
return "redirect:/gruppen2/";
|
||||
}
|
||||
|
||||
@ -326,6 +326,7 @@ public class WebController {
|
||||
@RequestParam("group_id") String groupId,
|
||||
KeycloakAuthenticationToken token) {
|
||||
Account account = keyCloakService.createAccountFromPrincipal(token);
|
||||
validationService.checkIfNewMaximumIsValid(maximum, groupId);
|
||||
controllerService.updateMaxUser(account, UUID.fromString(groupId), maximum);
|
||||
return "redirect:/gruppen2/details/members/" + groupId;
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ public class UpdateGroupDescriptionEvent extends Event {
|
||||
|
||||
public UpdateGroupDescriptionEvent(UUID groupId, String userId, String newGroupDescription) {
|
||||
super(groupId, userId);
|
||||
this.newGroupDescription = newGroupDescription;
|
||||
this.newGroupDescription = newGroupDescription.trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -20,7 +20,7 @@ public class UpdateGroupTitleEvent extends Event {
|
||||
|
||||
public UpdateGroupTitleEvent(UUID groupId, String userId, String newGroupTitle) {
|
||||
super(groupId, userId);
|
||||
this.newGroupTitle = newGroupTitle;
|
||||
this.newGroupTitle = newGroupTitle.trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -4,6 +4,6 @@ import org.springframework.http.HttpStatus;
|
||||
|
||||
public class WrongFileException extends EventException {
|
||||
public WrongFileException(String info) {
|
||||
super(HttpStatus.INTERNAL_SERVER_ERROR, "Die entsprechende Datei ist keine valide CSV-Datei!", info);
|
||||
super(HttpStatus.BAD_REQUEST, "Die entsprechende Datei ist keine valide CSV-Datei!", info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
|
||||
|
||||
@Bean
|
||||
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST,
|
||||
proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public AccessToken getAccessToken() {
|
||||
HttpServletRequest request =
|
||||
((ServletRequestAttributes) RequestContextHolder
|
||||
@ -61,17 +61,10 @@ class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
super.configure(http);
|
||||
http.authorizeRequests()
|
||||
.antMatchers("/actuator/**")
|
||||
.hasRole("monitoring")
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/h2-console/**")
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
.permitAll();
|
||||
|
||||
http.csrf().disable();
|
||||
http.headers().frameOptions().disable();
|
||||
.antMatchers("/actuator/**")
|
||||
.hasRole("monitoring")
|
||||
.anyRequest()
|
||||
.permitAll();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package mops.gruppen2.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
|
||||
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
|
||||
import mops.gruppen2.domain.Group;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.Role;
|
||||
@ -15,14 +17,19 @@ import mops.gruppen2.domain.event.UpdateRoleEvent;
|
||||
import mops.gruppen2.domain.event.UpdateUserMaxEvent;
|
||||
import mops.gruppen2.domain.exception.EventException;
|
||||
import mops.gruppen2.domain.exception.UserNotFoundException;
|
||||
import mops.gruppen2.domain.exception.WrongFileException;
|
||||
import mops.gruppen2.security.Account;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.CharConversionException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static mops.gruppen2.domain.Role.ADMIN;
|
||||
|
||||
@ -51,26 +58,15 @@ public class ControllerService {
|
||||
* @param title Gruppentitel
|
||||
* @param description Gruppenbeschreibung
|
||||
*/
|
||||
//TODO: better assignments
|
||||
//TODO: createGroup + createOrga auslagern
|
||||
public void createGroup(Account account, String title, String description, Boolean visibility, Boolean maxInfiniteUsers, Long userMaximum, UUID parent) throws EventException {
|
||||
Visibility visibility1;
|
||||
maxInfiniteUsers = maxInfiniteUsers != null;
|
||||
|
||||
if (maxInfiniteUsers) {
|
||||
userMaximum = 100000L;
|
||||
}
|
||||
|
||||
visibility = visibility == null;
|
||||
|
||||
if (visibility) {
|
||||
visibility1 = Visibility.PUBLIC;
|
||||
} else {
|
||||
visibility1 = Visibility.PRIVATE;
|
||||
}
|
||||
public UUID createGroup(Account account, String title, String description, Boolean isVisibilityPrivate, Boolean isLecture, Boolean isMaximumInfinite, Long userMaximum, UUID parent) throws EventException {
|
||||
userMaximum = checkInfiniteUsers(isMaximumInfinite, userMaximum);
|
||||
|
||||
Visibility groupVisibility = setGroupVisibility(isVisibilityPrivate);
|
||||
UUID groupId = UUID.randomUUID();
|
||||
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), parent, GroupType.SIMPLE, visibility1, userMaximum);
|
||||
|
||||
GroupType groupType = setGroupType(isLecture);
|
||||
|
||||
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), parent, groupType, groupVisibility, userMaximum);
|
||||
eventService.saveEvent(createGroupEvent);
|
||||
|
||||
inviteService.createLink(groupId);
|
||||
@ -79,45 +75,85 @@ public class ControllerService {
|
||||
updateTitle(account, groupId, title);
|
||||
updateDescription(account, groupId, description);
|
||||
updateRole(account.getName(), groupId);
|
||||
}
|
||||
|
||||
public UUID createOrga(Account account, String title, String description, Boolean visibility, Boolean lecture, Boolean maxInfiniteUsers, Long userMaximum, UUID parent) throws EventException, IOException {
|
||||
maxInfiniteUsers = maxInfiniteUsers != null;
|
||||
|
||||
if (maxInfiniteUsers) {
|
||||
userMaximum = 100000L;
|
||||
}
|
||||
|
||||
visibility = visibility == null;
|
||||
lecture = lecture != null;
|
||||
Visibility visibility1;
|
||||
UUID groupId = UUID.randomUUID();
|
||||
if (visibility) {
|
||||
visibility1 = Visibility.PUBLIC;
|
||||
} else {
|
||||
visibility1 = Visibility.PRIVATE;
|
||||
}
|
||||
|
||||
inviteService.createLink(groupId);
|
||||
|
||||
GroupType groupType;
|
||||
if (lecture) {
|
||||
groupType = GroupType.LECTURE;
|
||||
} else {
|
||||
groupType = GroupType.SIMPLE;
|
||||
}
|
||||
|
||||
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId, account.getName(), parent, groupType, visibility1, userMaximum);
|
||||
eventService.saveEvent(createGroupEvent);
|
||||
|
||||
addUser(account, groupId);
|
||||
updateTitle(account, groupId, title);
|
||||
updateDescription(account, groupId, description);
|
||||
updateRole(account.getName(), groupId);
|
||||
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void createGroupAsOrga(Account account, String title, String description, Boolean isVisibilityPrivate, Boolean isLecture, Boolean isMaximumInfinite, Long userMaximum, UUID parent, MultipartFile file) throws EventException, IOException {
|
||||
userMaximum = checkInfiniteUsers(isMaximumInfinite, userMaximum);
|
||||
|
||||
List<User> newUsers = readCsvFile(file);
|
||||
|
||||
List<User> oldUsers = new ArrayList<>();
|
||||
User user = new User(account.getName(), "", "", "");
|
||||
oldUsers.add(user);
|
||||
|
||||
removeOldUsersFromNewUsers(oldUsers, newUsers);
|
||||
|
||||
userMaximum = adjustUserMaximum((long) newUsers.size(), 1L, userMaximum);
|
||||
|
||||
UUID groupId = createGroup(account, title, description, isVisibilityPrivate, isLecture, isMaximumInfinite, userMaximum, parent);
|
||||
|
||||
inviteService.createLink(groupId);
|
||||
|
||||
addUserList(newUsers, groupId);
|
||||
}
|
||||
|
||||
private void removeOldUsersFromNewUsers(List<User> oldUsers, List<User> newUsers) {
|
||||
for (User oldUser : oldUsers) {
|
||||
newUsers.remove(oldUser);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Long checkInfiniteUsers(Boolean isMaximumInfinite, Long userMaximum) {
|
||||
isMaximumInfinite = isMaximumInfinite != null;
|
||||
|
||||
if (isMaximumInfinite) {
|
||||
userMaximum = 100000L;
|
||||
}
|
||||
|
||||
return userMaximum;
|
||||
}
|
||||
|
||||
private Visibility setGroupVisibility(Boolean isVisibilityPrivate) {
|
||||
isVisibilityPrivate = isVisibilityPrivate != null;
|
||||
|
||||
if (isVisibilityPrivate) {
|
||||
return Visibility.PRIVATE;
|
||||
} else {
|
||||
return Visibility.PUBLIC;
|
||||
}
|
||||
}
|
||||
|
||||
private GroupType setGroupType(Boolean isLecture) {
|
||||
isLecture = isLecture != null;
|
||||
if (isLecture) {
|
||||
return GroupType.LECTURE;
|
||||
} else {
|
||||
return GroupType.SIMPLE;
|
||||
}
|
||||
}
|
||||
|
||||
private List<User> readCsvFile(MultipartFile file) throws EventException, IOException {
|
||||
if (!file.isEmpty()) {
|
||||
try {
|
||||
List<User> userList = CsvService.read(file.getInputStream());
|
||||
return userList.stream().distinct().collect(Collectors.toList()); //filters duplicates from list
|
||||
} catch (UnrecognizedPropertyException | CharConversionException ex) {
|
||||
logger.warning("File konnte nicht gelesen werden");
|
||||
throw new WrongFileException(file.getOriginalFilename());
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private Long adjustUserMaximum(Long newUsers, Long oldUsers, Long maxUsers) {
|
||||
if (oldUsers + newUsers > maxUsers) {
|
||||
maxUsers = oldUsers + newUsers;
|
||||
}
|
||||
return maxUsers;
|
||||
}
|
||||
|
||||
public void addUser(Account account, UUID groupId) {
|
||||
AddUserEvent addUserEvent = new AddUserEvent(groupId, account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
|
||||
@ -151,7 +187,6 @@ public class ControllerService {
|
||||
eventService.saveEvent(updateUserMaxEvent);
|
||||
}
|
||||
|
||||
//TODO: updateRole + deleteUser, teilweise auslagern zu userInGroup oder sowas
|
||||
public void updateRole(String userId, UUID groupId) throws EventException {
|
||||
UpdateRoleEvent updateRoleEvent;
|
||||
Group group = userService.getGroupById(groupId);
|
||||
|
||||
@ -130,16 +130,37 @@ public class ValidationService {
|
||||
* @param userMaximum Das user Limit der Gruppe
|
||||
*/
|
||||
public void checkFields(String description, String title, Long userMaximum, Boolean maxInfiniteUsers) {
|
||||
if (description == null) {
|
||||
if (description == null || description.trim().length() == 0) {
|
||||
throw new BadParameterException("Die Beschreibung wurde nicht korrekt angegeben");
|
||||
}
|
||||
|
||||
if (title == null) {
|
||||
if (title == null || title.trim().length() == 0) {
|
||||
throw new BadParameterException("Der Titel wurde nicht korrekt angegeben");
|
||||
}
|
||||
|
||||
if (userMaximum == null && maxInfiniteUsers == null) {
|
||||
throw new BadParameterException("Teilnehmeranzahl wurde nicht korrekt angegeben");
|
||||
}
|
||||
|
||||
if (userMaximum != null) {
|
||||
if (userMaximum < 1 || userMaximum > 10000L) {
|
||||
throw new BadParameterException("Teilnehmeranzahl wurde nicht korrekt angegeben");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkIfNewMaximumIsValid(Long newUserMaximum, String groupId) {
|
||||
Group group = userService.getGroupById(UUID.fromString(groupId));
|
||||
if (newUserMaximum == null) {
|
||||
throw new BadParameterException("Es wurde keine neue maximale Teilnehmeranzahl angegeben!");
|
||||
}
|
||||
|
||||
if (newUserMaximum < 1 || newUserMaximum > 10000L) {
|
||||
throw new BadParameterException("Die neue maximale Teilnehmeranzahl wurde nicht korrekt angegeben!");
|
||||
}
|
||||
|
||||
if (group.getMembers().size() > newUserMaximum) {
|
||||
throw new BadParameterException("Die neue maximale Teilnehmeranzahl ist kleiner als die aktuelle Teilnehmeranzahl!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
application.name=gruppen2
|
||||
logging.pattern.console=[${application.name}],%magenta(%-5level), %d{dd-MM-yyyy HH:mm:ss.SSS}, %highlight(%msg),%thread,%logger.%M%n
|
||||
spring.datasource.platform=h2
|
||||
spring.datasource.url=jdbc:h2:mem:blogdb
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.driver-class-name=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||
spring.h2.console.enabled=true
|
||||
logging.level.org.springframework.jdbc.core=DEBUG
|
||||
spring.h2.console.enabled=false
|
||||
logging.level.org.springframework.jdbc.core=INFO
|
||||
keycloak.principal-attribute=preferred_username
|
||||
keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth
|
||||
keycloak.realm=MOPS
|
||||
@ -18,4 +19,3 @@ keycloak.use-resource-role-mappings=true
|
||||
keycloak.autodetect-bearer-only=true
|
||||
keycloak.confidential-port=443
|
||||
server.error.include-stacktrace=always
|
||||
server.port=8080
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
application.name=gruppen2
|
||||
logging.pattern.console=[${application.name}],%magenta(%-5level), %d{dd-MM-yyyy HH:mm:ss.SSS}, %highlight(%msg),%thread,%logger.%M%n
|
||||
|
||||
spring.datasource.initialization-mode=always
|
||||
spring.datasource.platform=mysql
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
spring.datasource.initialization-mode=NEVER
|
||||
spring.datasource.url=jdbc:mysql://dbmysql:3306/gruppen2
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=geheim
|
||||
|
||||
keycloak.principal-attribute=preferred_username
|
||||
keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth
|
||||
keycloak.realm=MOPS
|
||||
hhu_keycloak.token-uri=https://keycloak.cs.hhu.de/auth/realms/MOPS/protocol/openid-connect/token
|
||||
keycloak.resource=gruppenfindung
|
||||
keycloak.credentials.secret= fc6ebf10-8c63-4e71-a667-4eae4e8209a1
|
||||
keycloak.credentials.secret=fc6ebf10-8c63-4e71-a667-4eae4e8209a1
|
||||
keycloak.verify-token-audience=true
|
||||
keycloak.use-resource-role-mappings=true
|
||||
keycloak.autodetect-bearer-only=true
|
||||
|
||||
10
src/main/resources/schema-h2.sql
Normal file
10
src/main/resources/schema-h2.sql
Normal file
@ -0,0 +1,10 @@
|
||||
DROP TABLE IF EXISTS event;
|
||||
|
||||
CREATE TABLE event
|
||||
(
|
||||
event_id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
group_id VARCHAR(36) NOT NULL,
|
||||
user_id VARCHAR(50),
|
||||
event_type VARCHAR(32),
|
||||
event_payload VARCHAR(2500)
|
||||
);
|
||||
@ -40,7 +40,7 @@
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<h1>Metadaten ändern</h1>
|
||||
<form action="/gruppen2/details/changeMetadata" method="post">
|
||||
<form method="post" th:action="@{/gruppen2/details/changeMetadata}">
|
||||
<div class="shadow-sm p-2"
|
||||
style=" border: 10px solid aliceblue; background: aliceblue">
|
||||
<div class="form-group">
|
||||
|
||||
@ -38,7 +38,8 @@
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<h1>Gruppenerstellung</h1>
|
||||
<form method="post" action="/gruppen2/createOrga" enctype="multipart/form-data">
|
||||
<form enctype="multipart/form-data" method="post"
|
||||
th:action="@{/gruppen2/createOrga}">
|
||||
<div class="shadow-sm p-2"
|
||||
style=" border: 10px solid aliceblue; background: aliceblue">
|
||||
<div class="form-group">
|
||||
|
||||
@ -37,8 +37,9 @@
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<h1>Gruppenerstellung</h1>
|
||||
<form method="post" action="/gruppen2/createStudent">
|
||||
<div class="shadow-sm p-2" style=" border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
|
||||
<form method="post" th:action="@{/gruppen2/createStudent}">
|
||||
<div class="shadow-sm p-2"
|
||||
style=" border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="titel">Titel</label>
|
||||
|
||||
@ -35,12 +35,16 @@
|
||||
<div class="shadow-sm p-4 col-8"
|
||||
style="border: 10px solid aliceblue; display: inline-block; border-radius: 5px; background: aliceblue">
|
||||
<div class="row">
|
||||
<h1 style="color: black; font-weight: bold; font-optical-sizing: auto; overflow-wrap: break-word; width: 95%"
|
||||
th:text="${group.getTitle()}"></h1>
|
||||
<a class="fa fa-pencil"
|
||||
style="font-size:30px; width: 5%"
|
||||
th:href="@{/gruppen2/details/changeMetadata/{id}(id=${group.getId()})}"
|
||||
th:if="${roles.get(user.getId()) == admin}"></a>
|
||||
<div class="col-11">
|
||||
<h1 style="color: black; font-weight: bold; font-optical-sizing: auto; overflow-wrap: break-word; width: 95%"
|
||||
th:text="${group.getTitle()}"></h1>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<a class="fa fa-pencil"
|
||||
style="font-size:30px; width: 5%"
|
||||
th:href="@{/gruppen2/details/changeMetadata/{id}(id=${group.getId()})}"
|
||||
th:if="${roles.get(user.getId()) == admin}"></a>
|
||||
</div>
|
||||
</div>
|
||||
<h3>
|
||||
<span class="badge badge-pill badge-dark" style="background: darkslategray"
|
||||
@ -79,15 +83,16 @@
|
||||
style="background: #52a1eb; border: none; margin: 5px">
|
||||
<a style="color: white" th:href="@{/gruppen2}">Zurück</a>
|
||||
</button>
|
||||
<form action="/gruppen2/leaveGroup" method="post">
|
||||
<form method="post" th:action="@{/gruppen2/leaveGroup}">
|
||||
<button class="btn btn-danger" style="border-style: none; margin: 5px"
|
||||
th:name="group_id" th:value="${group.getId()}"
|
||||
type="submit">Gruppe verlassen
|
||||
</button>
|
||||
</form>
|
||||
<form action="/gruppen2/deleteGroup" method="post">
|
||||
<form method="post" th:action="@{/gruppen2/deleteGroup}">
|
||||
<button class="btn btn-danger" style="border-style: none; margin: 5px"
|
||||
th:name="group_id" th:value="${group.getId()}" th:if="${group.getRoles().get(user.getId()) == admin}"
|
||||
th:name="group_id" th:value="${group.getId()}"
|
||||
th:if="${group.getRoles().get(user.getId()) == admin}"
|
||||
type="submit">Gruppe löschen
|
||||
</button>
|
||||
</form>
|
||||
@ -128,7 +133,7 @@
|
||||
</div>
|
||||
<script>
|
||||
function copyLink() {
|
||||
var copyText = document.getElementById("groupLink");
|
||||
const copyText = document.getElementById("groupLink");
|
||||
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999);
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
</div>
|
||||
<div class="form-group mt-2">
|
||||
<div class="text-right">
|
||||
<form method="post" action="/gruppen2/detailsBeitreten">
|
||||
<form method="post" th:action="@{/gruppen2/detailsBeitreten}">
|
||||
<button class="btn btn-primary"
|
||||
style="background: #52a1eb; border-style: none;"
|
||||
th:href="@{/gruppen2/detailsBeitreten}"
|
||||
|
||||
@ -48,16 +48,19 @@
|
||||
</div>
|
||||
<div class="shadow p-2" style="border: 10px solid aliceblue; background: aliceblue">
|
||||
<div class="form-group pt-4" th:if="${account.getRoles().contains('orga')}">
|
||||
<form action="/gruppen2/details/members/addUsersFromCsv"
|
||||
<form th:action="@{/gruppen2/details/members/addUsersFromCsv}"
|
||||
enctype="multipart/form-data"
|
||||
method="post">
|
||||
<div class="input-group mb-3">
|
||||
<div class="custom-file">
|
||||
<input class="custom-file-input" id="file" th:name="file" type="file">
|
||||
<label class="custom-file-label" for="file">CSV Datei von Mitgliedern hochladen</label>
|
||||
<input class="custom-file-input" id="file" th:name="file"
|
||||
type="file">
|
||||
<label class="custom-file-label" for="file">CSV Datei von
|
||||
Mitgliedern hochladen</label>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" style="background: #52a1eb; border-style: none"
|
||||
<button class="btn btn-outline-secondary"
|
||||
style="background: #52a1eb; border-style: none"
|
||||
th:name="group_id" th:value="${group.getId()}"
|
||||
type="submit">
|
||||
<a style="color: white">Hinzufügen</a>
|
||||
@ -67,12 +70,16 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="form-group pt-4">
|
||||
<form action="/gruppen2/details/members/changeMaximum" method="post">
|
||||
<form method="post" th:action="@{/gruppen2/details/members/changeMaximum}">
|
||||
<div class="input-group mb-3" id="userMaximum">
|
||||
<input class="form-control" placeholder="Maximale Teilnehmerzahl ändern..." th:name="maximum"
|
||||
type="number" th:min="${group.getMembers().size()}" max="10000">
|
||||
<input class="form-control"
|
||||
placeholder="Maximale Teilnehmerzahl ändern..."
|
||||
th:name="maximum"
|
||||
type="number" th:min="${group.getMembers().size()}"
|
||||
max="10000">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" style="background: #52a1eb; border-style: none"
|
||||
<button class="btn btn-outline-secondary"
|
||||
style="background: #52a1eb; border-style: none"
|
||||
th:name="group_id" th:value="${group.getId()}"
|
||||
type="submit">
|
||||
<a style="color: white">Speichern</a>
|
||||
@ -99,21 +106,27 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-right btn-toolbar" style="float: right;" role="toolbar">
|
||||
<form action="/gruppen2/details/members/changeRole" method="post">
|
||||
<form method="post"
|
||||
th:action="@{/gruppen2/details/members/changeRole}">
|
||||
<input th:name="group_id" th:value="${group.getId()}"
|
||||
type="hidden">
|
||||
<input th:name="user_id" th:value="${member.getId()}"
|
||||
type="hidden">
|
||||
<button class="btn btn-warning btn-sm" type="submit" style="margin: 5px">Rolle
|
||||
<button class="btn btn-warning btn-sm" type="submit"
|
||||
style="margin: 5px">Rolle
|
||||
ändern
|
||||
</button>
|
||||
</form>
|
||||
<form action="/gruppen2/details/members/deleteUser" method="post">
|
||||
<form method="post"
|
||||
th:action="@{/gruppen2/details/members/deleteUser}">
|
||||
<input th:name="group_id" th:value="${group.getId()}"
|
||||
type="hidden">
|
||||
<input th:name="user_id" th:value="${member.getId()}"
|
||||
type="hidden">
|
||||
<button class="btn btn-danger btn-sm" style="margin: 5px" th:if='!${account.getName().equals(member.getId())}'>Mitglied entfernen</button>
|
||||
<button class="btn btn-danger btn-sm" style="margin: 5px"
|
||||
th:if='!${account.getName().equals(member.getId())}'>
|
||||
Mitglied entfernen
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<h1>Meine Gruppen</h1>
|
||||
<form action="/" method="get">
|
||||
<form method="get" th:action="@{/}">
|
||||
<h3 style="color: dodgerblue; font-weight: bold; font-optical-sizing: auto">
|
||||
<small style="font-weight: normal; color: black">Mitglied in </small>
|
||||
<small style="font-weight: bold; color: black"
|
||||
|
||||
@ -10,7 +10,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navigation navigation-secondary" is="mops-navigation" th:fragment="navigation" th:switch="${account.getRoles().contains('orga')}">
|
||||
<nav class="navigation navigation-secondary" is="mops-navigation" th:fragment="navigation"
|
||||
th:switch="${account.getRoles().contains('orga')}">
|
||||
<ul>
|
||||
<li>
|
||||
<a th:href="@{/gruppen2}" href="/">Gruppen</a>
|
||||
@ -32,20 +33,26 @@
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<h1>Gruppensuche</h1>
|
||||
<form action="/gruppen2/findGroup" method="get">
|
||||
<div class="shadow-sm p-2" 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"
|
||||
placeholder="z.B. Programmieren, Lerngruppe, ..."
|
||||
th:name="suchbegriff" type="text">
|
||||
</div>
|
||||
<button class="btn btn-primary"
|
||||
style="background: #52a1eb; border-style: none"
|
||||
type="submit">Suchen
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="shadow-sm p-2"
|
||||
style="border: 10px solid aliceblue; border-radius: 5px; background: aliceblue">
|
||||
<form method="get" th:action="@{/gruppen2/findGroup}">
|
||||
<div class="form-group">
|
||||
<label for="suchleiste">Suchbegriff:</label>
|
||||
<input class="form-control" id="suchleiste"
|
||||
placeholder="z.B. Programmieren, Lerngruppe, ..."
|
||||
th:name="suchbegriff" type="text">
|
||||
</div>
|
||||
<button class="btn btn-primary"
|
||||
style="background: #52a1eb; border-style: none"
|
||||
type="submit">Suchen
|
||||
</button>
|
||||
<button class="btn btn-primary"
|
||||
style="background: deepskyblue; border-style: none"
|
||||
type="submit">
|
||||
<a style="color: white" href="/gruppen2/findGroup?suchbegriff=">Alle anzeigen</a>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<br>
|
||||
<table class="table">
|
||||
<!-- Erscheint dann, wenn man "Suchen" Button klickt und Ergebnisse angezeigt werden, aber so solls aussehen -->
|
||||
|
||||
Reference in New Issue
Block a user