Added possibility for user to hide from global score list

This commit is contained in:
Martin Asprusten 2026-04-16 20:39:39 +02:00
parent 753b757d57
commit 3b265735ec
No known key found for this signature in database
10 changed files with 379 additions and 295 deletions

View File

@ -94,6 +94,7 @@
</div>
<div class="other-users-div">
<h3>Andre aktive:</h3>
<input type="checkbox" id="hideMeCheckbox" x-model="$store.state.data.isHidden" x-on:click="$store.state.onClickHideCheckbox" /><label id="hideMeLabel" for="hideMeCheckbox">Skjul meg fra den globale listen</label>
<table>
<tr>
<th>Navn</th><th>Total avstand</th><th>Første aktivitet</th><th>Siste aktivitet</th>

View File

@ -33,6 +33,8 @@ interface AlpineState {
removeAdministrator: (userId: number) => void,
deleteUser: (userId: number) => void,
onClickHideCheckbox: (event: Event) => void,
init: () => void,
setServerMessage: (newMessage: Sykkelaksjon) => void,
getServerMessage: () => Sykkelaksjon,
@ -59,6 +61,8 @@ let alpineState: AlpineState = {
removeAdministrator: removeAdministrator,
deleteUser: deleteUser,
onClickHideCheckbox: onClickHideCheckbox,
init() {
this.data = defaultData;
},
@ -290,4 +294,21 @@ await refreshData();
if (receivedData) {
loadingDiv?.setAttribute("style", "display: none");
contentDiv?.setAttribute("style", "display: block");
}
function onClickHideCheckbox(event: PointerEvent) {
let possibleCheckbox = event.target;
if (possibleCheckbox instanceof HTMLInputElement) {
let formData = new FormData();
let url;
let isChecked = possibleCheckbox.checked;
if (isChecked) {
url = apiUrl + "/hideMe"
} else {
url = apiUrl + "/showMe"
}
submitFormToUrl(url, formData, "PUT");
}
}

View File

@ -17,6 +17,10 @@ export interface Sykkelaksjon {
* Whether the connected user is an administrator
*/
isAdmin: boolean;
/**
* Whether the connected user is hidden from the score lists
*/
isHidden?: boolean;
/**
* Available types of activities
*/
@ -69,6 +73,10 @@ export interface Sykkelaksjon {
* Administrator info: whether the user listed is an administrator
*/
isAdmin?: boolean;
/**
* Administrator info: whether the user is hidden from the global score table
*/
isHidden?: boolean;
/**
* Administrator info: the activity templates this user has defined
*/

View File

@ -100,4 +100,8 @@ summary {
font-weight: bold;
margin: -0.5em -0.5em 0;
padding: 0.5em;
}
#hideMeLabel {
width: 80%;
}

View File

@ -13,6 +13,10 @@
"type": "boolean",
"description": "Whether the connected user is an administrator"
},
"isHidden": {
"type": "boolean",
"description": "Whether the connected user is hidden from the score lists"
},
"activityTypes": {
"type": "array",
"description": "Available types of activities",
@ -77,6 +81,10 @@
"type": "boolean",
"description": "Administrator info: whether the user listed is an administrator"
},
"isHidden": {
"type": "boolean",
"description": "Administrator info: whether the user is hidden from the global score table"
},
"activityTemplates": {
"type": "array",
"description": "Administrator info: the activity templates this user has defined",

View File

@ -26,332 +26,363 @@ import java.util.List;
@RestController
@SpringBootApplication
public class Server {
@Autowired
private ProfileManager profileManager;
@Autowired
private UserService userService;
@Autowired
private ActivityTypeService activityTypeService;
@Autowired
private ActivityService activityService;
@Autowired
private ActivityTemplateService activityTemplateService;
@Autowired
private ProfileManager profileManager;
@Autowired
private UserService userService;
@Autowired
private ActivityTypeService activityTypeService;
@Autowired
private ActivityService activityService;
@Autowired
private ActivityTemplateService activityTemplateService;
@Value("${sykkelaksjon.openid.discoveryURI}")
private String discoveryURI;
@Value("${sykkelaksjon.openid.discoveryURI}")
private String discoveryURI;
@Value("${sykkelaksjon.openid.clientId}")
private String clientId;
@Value("${sykkelaksjon.openid.clientId}")
private String clientId;
@Value("$(sykkelaksjon.base-url)")
private String baseUrl;
@Value("$(sykkelaksjon.base-url)")
private String baseUrl;
private ActivityType getActivityTypeMessage(no.asprusten.sykkelaksjon.db.datatypes.ActivityType activityType) {
ActivityType activityTypeMessage = new ActivityType();
activityTypeMessage.setId(activityType.getId());
activityTypeMessage.setName(activityType.getActivityType());
activityTypeMessage.setConversionFactor(activityType.getConversion());
activityTypeMessage.setUnit(activityType.getUnit());
return activityTypeMessage;
}
private ActivityType getActivityTypeMessage(no.asprusten.sykkelaksjon.db.datatypes.ActivityType activityType) {
ActivityType activityTypeMessage = new ActivityType();
activityTypeMessage.setId(activityType.getId());
activityTypeMessage.setName(activityType.getActivityType());
activityTypeMessage.setConversionFactor(activityType.getConversion());
activityTypeMessage.setUnit(activityType.getUnit());
return activityTypeMessage;
}
private ActivityTemplate getActivityTemplateMessage(no.asprusten.sykkelaksjon.db.datatypes.ActivityTemplate activityTemplate) {
ActivityTemplate templateMessage = new ActivityTemplate();
templateMessage.setId(activityTemplate.getId());
templateMessage.setActivityType(getActivityTypeMessage(activityTemplate.getActivityType()));
templateMessage.setName(activityTemplate.getName());
templateMessage.setNumberOfUnits(activityTemplate.getNumberOfUnits());
return templateMessage;
}
private ActivityTemplate getActivityTemplateMessage(no.asprusten.sykkelaksjon.db.datatypes.ActivityTemplate activityTemplate) {
ActivityTemplate templateMessage = new ActivityTemplate();
templateMessage.setId(activityTemplate.getId());
templateMessage.setActivityType(getActivityTypeMessage(activityTemplate.getActivityType()));
templateMessage.setName(activityTemplate.getName());
templateMessage.setNumberOfUnits(activityTemplate.getNumberOfUnits());
return templateMessage;
}
private Activity getActivityMessage(no.asprusten.sykkelaksjon.db.datatypes.Activity activity) {
Activity activityMessage = new Activity();
activityMessage.setId(activity.getId());
activityMessage.setActivityType(getActivityTypeMessage(activity.getActivityType()));
activityMessage.setDescription(activity.getDescription());
activityMessage.setNumberOfUnits(activity.getNumberOfUnits());
activityMessage.setDate(activity.getDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
return activityMessage;
}
private Activity getActivityMessage(no.asprusten.sykkelaksjon.db.datatypes.Activity activity) {
Activity activityMessage = new Activity();
activityMessage.setId(activity.getId());
activityMessage.setActivityType(getActivityTypeMessage(activity.getActivityType()));
activityMessage.setDescription(activity.getDescription());
activityMessage.setNumberOfUnits(activity.getNumberOfUnits());
activityMessage.setDate(activity.getDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
return activityMessage;
}
@CrossOrigin
@GetMapping("/api")
public ServerMessageSchema respondToRequest() throws ServerExceptionHandler.InvalidUserException {
var optionalUserProfile = profileManager.getProfile();
if (optionalUserProfile.isEmpty()) {
throw new ServerExceptionHandler.InvalidUserException();
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@GetMapping("/api")
public ServerMessageSchema respondToRequest() throws ServerExceptionHandler.InvalidUserException {
var optionalUserProfile = profileManager.getProfile();
if (optionalUserProfile.isEmpty()) {
throw new ServerExceptionHandler.InvalidUserException();
}
var userProfile = optionalUserProfile.get();
var userProfile = optionalUserProfile.get();
var optionalUser = userService.getUser(userProfile.getUsername());
var optionalUser = userService.getUser(userProfile.getUsername());
var user = optionalUser
.orElseGet(
() -> userService.createUser(
userProfile.getUsername(),
userProfile.getAttribute("name").toString()
)
);
.orElseGet(
() -> userService.createUser(
userProfile.getUsername(),
userProfile.getAttribute("name").toString()
)
);
var allUsers = userService.list();
ServerMessageSchema serverMessage = new ServerMessageSchema();
serverMessage.setName(user.getFullName());
serverMessage.setIsAdmin(user.isAdmin());
var allUsers = userService.list();
ServerMessageSchema serverMessage = new ServerMessageSchema();
serverMessage.setName(user.getFullName());
serverMessage.setIsAdmin(user.isAdmin());
serverMessage.setIsHidden(user.isHidden());
boolean unitConversionNecessary = false;
for (var activityType : activityTypeService.list()) {
serverMessage.getActivityTypes().add(getActivityTypeMessage(activityType));
unitConversionNecessary |= activityType.getConversion() != 1.0;
}
serverMessage.setUnitConversionNecessary(unitConversionNecessary);
boolean unitConversionNecessary = false;
for (var activityType : activityTypeService.list()) {
serverMessage.getActivityTypes().add(getActivityTypeMessage(activityType));
unitConversionNecessary |= activityType.getConversion() != 1.0;
}
serverMessage.setUnitConversionNecessary(unitConversionNecessary);
for (var activityTemplate : user.getTemplates()) {
serverMessage.getActivityTemplates().add(getActivityTemplateMessage(activityTemplate));
}
for (var activityTemplate : user.getTemplates()) {
serverMessage.getActivityTemplates().add(getActivityTemplateMessage(activityTemplate));
}
List<Activity> unsortedActivities = new ArrayList<>();
List<Activity> unsortedActivities = new ArrayList<>();
for (var activity : user.getActivities()) {
unsortedActivities.add(getActivityMessage(activity));
}
unsortedActivities.sort(Comparator.comparing(Activity::getDate));
serverMessage.getActivities().addAll(unsortedActivities.reversed());
for (var activity : user.getActivities()) {
unsortedActivities.add(getActivityMessage(activity));
}
unsortedActivities.sort(Comparator.comparing(Activity::getDate));
serverMessage.getActivities().addAll(unsortedActivities.reversed());
List<OtherUser> unsortedOtherUsers = new ArrayList<>();
for (var otherUser : allUsers) {
// Don't describe the current user
if (otherUser.getId().equals(user.getId())) {
continue;
}
// If this is not an active user, and the requesting user is not an admin, skip
if (!otherUser.isActive() && !user.isAdmin()) {
continue;
}
List<OtherUser> unsortedOtherUsers = new ArrayList<>();
for (var otherUser : allUsers) {
// Don't describe the current user
if (otherUser.getId().equals(user.getId())) {
continue;
}
// If this is not an active user, and the requesting user is not an admin, skip
if (!otherUser.isActive() && !user.isAdmin()) {
continue;
}
// If the user has not registered anything yet, also skip it (unless admin)
if (otherUser.getActivities().isEmpty() && !user.isAdmin()) {
continue;
}
// If the user has not registered anything yet, also skip it (unless admin)
if (otherUser.getActivities().isEmpty() && !user.isAdmin()) {
continue;
}
OtherUser otherUserMessage = new OtherUser();
otherUserMessage.setName(otherUser.getFullName());
if (otherUser.isHidden() && !user.isAdmin()) {
continue;
}
double totalKilometers = otherUser.getActivities()
.stream()
.mapToDouble(activity -> activity.getActivityType().getConversion() * activity.getNumberOfUnits())
.sum();
otherUserMessage.setTotalKilometers(totalKilometers);
OtherUser otherUserMessage = new OtherUser();
otherUserMessage.setName(otherUser.getFullName());
otherUser.getActivities().stream()
.map(no.asprusten.sykkelaksjon.db.datatypes.Activity::getDate)
.min(LocalDate::compareTo)
.ifPresent(earliestDate ->
otherUserMessage.setEarliestActivity(earliestDate.format(DateTimeFormatter.ISO_LOCAL_DATE))
);
double totalKilometers = otherUser.getActivities()
.stream()
.mapToDouble(activity -> activity.getActivityType().getConversion() * activity.getNumberOfUnits())
.sum();
otherUserMessage.setTotalKilometers(totalKilometers);
otherUser.getActivities().stream()
.map(no.asprusten.sykkelaksjon.db.datatypes.Activity::getDate)
.max(LocalDate::compareTo)
.ifPresent(latestDate ->
otherUserMessage.setLatestActivity(latestDate.format(DateTimeFormatter.ISO_LOCAL_DATE))
);
otherUser.getActivities().stream()
.map(no.asprusten.sykkelaksjon.db.datatypes.Activity::getDate)
.min(LocalDate::compareTo)
.ifPresent(earliestDate ->
otherUserMessage.setEarliestActivity(earliestDate.format(DateTimeFormatter.ISO_LOCAL_DATE))
);
// Additional info is only for administrators
if (user.isAdmin()) {
otherUserMessage.setUserId(otherUser.getId());
otherUserMessage.setUserName(otherUser.getUsername());
otherUserMessage.setIsActive(otherUser.isActive());
otherUserMessage.setIsAdmin(otherUser.isAdmin());
List<Activity> userUnsortedActivities = new ArrayList<>();
for (var activity : otherUser.getActivities()) {
userUnsortedActivities.add(getActivityMessage(activity));
}
userUnsortedActivities.sort(Comparator.comparing(Activity::getDate));
otherUserMessage.getActivities().addAll(userUnsortedActivities.reversed());
otherUser.getActivities().stream()
.map(no.asprusten.sykkelaksjon.db.datatypes.Activity::getDate)
.max(LocalDate::compareTo)
.ifPresent(latestDate ->
otherUserMessage.setLatestActivity(latestDate.format(DateTimeFormatter.ISO_LOCAL_DATE))
);
for (var activityTemplate : otherUser.getTemplates()) {
otherUserMessage.getActivityTemplates().add(getActivityTemplateMessage(activityTemplate));
}
}
// Additional info is only for administrators
if (user.isAdmin()) {
otherUserMessage.setUserId(otherUser.getId());
otherUserMessage.setUserName(otherUser.getUsername());
otherUserMessage.setIsActive(otherUser.isActive());
otherUserMessage.setIsAdmin(otherUser.isAdmin());
otherUserMessage.setIsHidden(otherUser.isHidden());
List<Activity> userUnsortedActivities = new ArrayList<>();
for (var activity : otherUser.getActivities()) {
userUnsortedActivities.add(getActivityMessage(activity));
}
userUnsortedActivities.sort(Comparator.comparing(Activity::getDate));
otherUserMessage.getActivities().addAll(userUnsortedActivities.reversed());
unsortedOtherUsers.add(otherUserMessage);
}
for (var activityTemplate : otherUser.getTemplates()) {
otherUserMessage.getActivityTemplates().add(getActivityTemplateMessage(activityTemplate));
}
}
unsortedOtherUsers.sort(Comparator.comparing(OtherUser::getTotalKilometers));
serverMessage.getOtherUsers().addAll(unsortedOtherUsers.reversed());
return serverMessage;
}
unsortedOtherUsers.add(otherUserMessage);
}
@CrossOrigin
@PostMapping(path = "/api/submitActivity", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void submitActivity(
@RequestParam("activity-type") Long activityTypeId,
@RequestParam("activity-distance") double distance,
@RequestParam("activity-description") String description,
@RequestParam("activity-date") String date
) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityTypeService.getById(activityTypeId).ifPresent(activityType -> {
no.asprusten.sykkelaksjon.db.datatypes.Activity activity = new no.asprusten.sykkelaksjon.db.datatypes.Activity(
activityType,
dbUser,
distance,
description,
LocalDate.parse(date)
);
activityService.saveActivity(activity);
});
});
});
}
unsortedOtherUsers.sort(Comparator.comparing(OtherUser::getTotalKilometers));
serverMessage.getOtherUsers().addAll(unsortedOtherUsers.reversed());
return serverMessage;
}
@CrossOrigin
@PostMapping(path = "/api/submitActivityTemplate", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void submitActivityTemplate(
@RequestParam("activity-type") Long activityTypeId,
@RequestParam("activity-distance") double distance,
@RequestParam("activity-description") String description,
@RequestParam("activity-date") String date
) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityTypeService.getById(activityTypeId).ifPresent(activityType -> {
no.asprusten.sykkelaksjon.db.datatypes.ActivityTemplate activityTemplate = new no.asprusten.sykkelaksjon.db.datatypes.ActivityTemplate(
dbUser,
activityType,
description,
distance
);
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@PostMapping(path = "/api/submitActivity", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void submitActivity(
@RequestParam("activity-type") Long activityTypeId,
@RequestParam("activity-distance") double distance,
@RequestParam("activity-description") String description,
@RequestParam("activity-date") String date
) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityTypeService.getById(activityTypeId).ifPresent(activityType -> {
no.asprusten.sykkelaksjon.db.datatypes.Activity activity = new no.asprusten.sykkelaksjon.db.datatypes.Activity(
activityType,
dbUser,
distance,
description,
LocalDate.parse(date)
);
activityService.saveActivity(activity);
});
});
});
}
activityTemplateService.saveActivityTemplate(activityTemplate);
});
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@PostMapping(path = "/api/submitActivityTemplate", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void submitActivityTemplate(
@RequestParam("activity-type") Long activityTypeId,
@RequestParam("activity-distance") double distance,
@RequestParam("activity-description") String description,
@RequestParam("activity-date") String date
) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityTypeService.getById(activityTypeId).ifPresent(activityType -> {
no.asprusten.sykkelaksjon.db.datatypes.ActivityTemplate activityTemplate = new no.asprusten.sykkelaksjon.db.datatypes.ActivityTemplate(
dbUser,
activityType,
description,
distance
);
@CrossOrigin
@DeleteMapping(path = "/api/deleteActivityTemplate", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteActivityTemplate(@RequestParam("activity-template-id") Long activityTemplateId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityTemplateService.findById(activityTemplateId).ifPresent(activityTemplate -> {
if (activityTemplate.getOwner().equals(dbUser)) {
activityTemplateService.deleteActivityTemplate(activityTemplate.getId());
}
});
});
});
}
activityTemplateService.saveActivityTemplate(activityTemplate);
});
});
});
}
@CrossOrigin
@DeleteMapping(path = "/api/deleteActivity", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteActivity(@RequestParam("activity-id") Long activityId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityService.findById(activityId).ifPresent(activity -> {
if (activity.getActivityOwner().equals(dbUser) || dbUser.isAdmin()) {
activityService.deleteActivity(activityId);
}
});
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@DeleteMapping(path = "/api/deleteActivityTemplate", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteActivityTemplate(@RequestParam("activity-template-id") Long activityTemplateId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityTemplateService.findById(activityTemplateId).ifPresent(activityTemplate -> {
if (activityTemplate.getOwner().equals(dbUser)) {
activityTemplateService.deleteActivityTemplate(activityTemplate.getId());
}
});
});
});
}
@CrossOrigin
@PostMapping(path = "/api/addActivityType", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void createActivityType(
@RequestParam("activity-type-name") String name,
@RequestParam("activity-type-unit") String unit,
@RequestParam("activity-type-conversion-factor") double conversionFactor
) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
no.asprusten.sykkelaksjon.db.datatypes.ActivityType activityType = new no.asprusten.sykkelaksjon.db.datatypes.ActivityType(
name, unit, conversionFactor
);
activityTypeService.saveActivityType(activityType);
}
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@DeleteMapping(path = "/api/deleteActivity", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteActivity(@RequestParam("activity-id") Long activityId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
activityService.findById(activityId).ifPresent(activity -> {
if (activity.getActivityOwner().equals(dbUser) || dbUser.isAdmin()) {
activityService.deleteActivity(activityId);
}
});
});
});
}
@CrossOrigin
@DeleteMapping(path = "/api/deleteActivityType", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteActivityType(@RequestParam("activity-type-id") Long activityTypeId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
activityTypeService.deleteActivityType(activityTypeId);
}
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@PostMapping(path = "/api/addActivityType", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void createActivityType(
@RequestParam("activity-type-name") String name,
@RequestParam("activity-type-unit") String unit,
@RequestParam("activity-type-conversion-factor") double conversionFactor
) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
no.asprusten.sykkelaksjon.db.datatypes.ActivityType activityType = new no.asprusten.sykkelaksjon.db.datatypes.ActivityType(
name, unit, conversionFactor
);
activityTypeService.saveActivityType(activityType);
}
});
});
}
@CrossOrigin
@PutMapping(path = "/api/makeAdmin", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void makeAdmin(@RequestParam("user-id") Long userId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
userService.getUserById(userId).ifPresent(elevatedUser -> {
elevatedUser.setAdmin(true);
userService.saveUser(elevatedUser);
});
}
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@DeleteMapping(path = "/api/deleteActivityType", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteActivityType(@RequestParam("activity-type-id") Long activityTypeId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
activityTypeService.deleteActivityType(activityTypeId);
}
});
});
}
@CrossOrigin
@PutMapping(path = "/api/removeAdmin", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void removeAdmin(@RequestParam("user-id") Long userId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
userService.getUserById(userId).ifPresent(elevatedUser -> {
elevatedUser.setAdmin(false);
userService.saveUser(elevatedUser);
});
}
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@PutMapping(path = "/api/makeAdmin", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void makeAdmin(@RequestParam("user-id") Long userId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
userService.getUserById(userId).ifPresent(elevatedUser -> {
elevatedUser.setAdmin(true);
userService.saveUser(elevatedUser);
});
}
});
});
}
@CrossOrigin
@DeleteMapping(path = "/api/deleteUser", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteUser(@RequestParam("user-id") Long userId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
userService.deleteUserById(userId);
}
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@PutMapping(path = "/api/removeAdmin", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void removeAdmin(@RequestParam("user-id") Long userId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
userService.getUserById(userId).ifPresent(elevatedUser -> {
elevatedUser.setAdmin(false);
userService.saveUser(elevatedUser);
});
}
});
});
}
@CrossOrigin
@GetMapping(path = "/api/openid")
public OpenidSchema provideOpenidConfig() {
OpenidSchema openidSchema = new OpenidSchema();
openidSchema.setClientId(clientId);
openidSchema.setOpenidDiscoveryUri(discoveryURI);
return openidSchema;
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@DeleteMapping(path = "/api/deleteUser", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void deleteUser(@RequestParam("user-id") Long userId) {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
if (dbUser.isAdmin()) {
userService.deleteUserById(userId);
}
});
});
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Server.class);
application.addListeners(new PropertiesListener());
application.run(args);
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@GetMapping(path = "/api/openid")
public OpenidSchema provideOpenidConfig() {
OpenidSchema openidSchema = new OpenidSchema();
openidSchema.setClientId(clientId);
openidSchema.setOpenidDiscoveryUri(discoveryURI);
return openidSchema;
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@PutMapping(path = "/api/hideMe")
public void hideUser() {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
dbUser.setHidden(true);
userService.saveUser(dbUser);
});
});
}
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
@PutMapping(path = "/api/showMe")
public void showUser() {
profileManager.getProfile().ifPresent(userProfile -> {
String username = userProfile.getUsername();
userService.getUser(username).ifPresent(dbUser -> {
dbUser.setHidden(false);
userService.saveUser(dbUser);
});
});
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Server.class);
application.addListeners(new PropertiesListener());
application.run(args);
}
}

View File

@ -10,7 +10,7 @@ public class Activity {
@GeneratedValue
private long id;
@ManyToOne( optional = false)
@ManyToOne(optional = false)
private ActivityType activityType;
@ManyToOne(optional = false)
private WebUser activityOwner;

View File

@ -4,7 +4,7 @@ import jakarta.persistence.*;
@Entity
@Table(uniqueConstraints = {
@UniqueConstraint(name = "UniqueNamesPerUser", columnNames = { "owner", "name" })
@UniqueConstraint(name = "UniqueNamesPerUser", columnNames = {"owner", "name"})
})
public class ActivityTemplate {
@Id

View File

@ -7,7 +7,7 @@ import java.util.List;
@Entity
@Table(uniqueConstraints = {
@UniqueConstraint(name = "OnlyOneActiveWithUsername", columnNames = { "username", "zeroIfActive" })
@UniqueConstraint(name = "OnlyOneActiveWithUsername", columnNames = {"username", "zeroIfActive"})
})
public class WebUser {
@Id
@ -20,6 +20,8 @@ public class WebUser {
private boolean isAdmin;
@Column(nullable = false)
private Long zeroIfActive;
@Column(nullable = false)
private boolean isHidden = false;
@OneToMany(mappedBy = "activityOwner", fetch = FetchType.EAGER)
private List<Activity> activities = new ArrayList<>();
@ -70,6 +72,14 @@ public class WebUser {
isAdmin = admin;
}
public boolean isHidden() {
return isHidden;
}
public void setHidden(boolean hidden) {
isHidden = hidden;
}
public void setActive(boolean active) {
if (active) {
zeroIfActive = 0L;

View File

@ -7,7 +7,8 @@ import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class ServerExceptionHandler {
public static class InvalidUserException extends Exception {}
public static class InvalidUserException extends Exception {
}
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(InvalidUserException.class)