Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin view user #58

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import net.furizon.backend.infrastructure.media.dto.MediaResponse;
import net.furizon.backend.infrastructure.pretix.service.PretixInformation;
import net.furizon.backend.infrastructure.security.FurizonUser;
import net.furizon.backend.infrastructure.security.annotation.PermissionRequired;
import net.furizon.backend.infrastructure.security.permissions.Permission;
import net.furizon.backend.infrastructure.usecase.UseCaseExecutor;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
Expand Down Expand Up @@ -58,9 +60,36 @@ public class BadgeController {
)
);
}
@Operation(summary = "Uploads the specified user's badge", description =
"This method is intended for admin use only"
+ "This method excepts the badge to be correctly cropped and resized. "
+ "If the ratio is not 1:1, the image will be cropped top left. If it has "
+ "an invalid size or dimensions, we will return with an error. We return "
+ "the media id and the relative path where the file is served")
@PermissionRequired(permissions = {Permission.CAN_MANAGE_USER_PUBLIC_INFO})
@PostMapping(value = "/user/upload/{userId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public @NotNull MediaResponse userUpload(
@AuthenticationPrincipal @Valid @NotNull final FurizonUser user,
@PathVariable @Valid @NotNull final Long userId,
@RequestParam("image") @NotNull MultipartFile image
) {
FurizonUser destUser = FurizonUser.builder()
.userId(userId)
.sessionId(user.getSessionId())
.authentication(user.getAuthentication())
.build();
return useCaseExecutor.execute(
UploadBadgeUsecase.class,
new UploadBadgeUsecase.Input(
destUser,
image,
BadgeType.BADGE_USER,
null
)
);
}
@Operation(summary = "Uploads the fursuit's badge", description =
"Using "
+ "This method excepts the badge to be correctly cropped and resized. "
"This method excepts the badge to be correctly cropped and resized. "
+ "If the ratio is not 1:1, the image will be cropped top left. If it has "
+ "an invalid size or dimensions, we will return with an error. We return "
+ "the media id and the relative path where the file is served")
Expand All @@ -81,14 +110,30 @@ public class BadgeController {
);
}

@Operation(summary = "Deletes the user's badge")
@DeleteMapping(value = "/user/")
public boolean deleteUserUpload(
@AuthenticationPrincipal @Valid @NotNull final FurizonUser user
) {
return useCaseExecutor.execute(
DeleteBadgeUseCase.class,
new DeleteBadgeUseCase.Input(
user,
user.getUserId(),
BadgeType.BADGE_USER,
null
)
);
}
@Operation(summary = "Deletes the specified user's badge")
@DeleteMapping(value = "/user/{userId}")
public boolean deleteUserUpload(
@AuthenticationPrincipal @Valid @NotNull final FurizonUser user,
@PathVariable @Valid @NotNull final Long userId
) {
return useCaseExecutor.execute(
DeleteBadgeUseCase.class,
new DeleteBadgeUseCase.Input(
userId,
BadgeType.BADGE_USER,
null
)
Expand All @@ -102,7 +147,7 @@ public boolean deleteFursuitUpload(
return useCaseExecutor.execute(
DeleteBadgeUseCase.class,
new DeleteBadgeUseCase.Input(
user,
user.getUserId(),
BadgeType.BADGE_FURSUIT,
fursuitId
)
Expand All @@ -123,7 +168,7 @@ public boolean deleteFursuitUpload(
return useCaseExecutor.execute(
GetFullInfoBadgeUseCase.class,
new GetFullInfoBadgeUseCase.Input(
user,
user.getUserId(),
pretixInformation
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import net.furizon.backend.feature.fursuits.dto.FursuitData;
import net.furizon.backend.feature.user.dto.UserDisplayData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.OffsetDateTime;
import java.util.List;

@Data
public class FullInfoBadgeResponse {
@NotNull private final UserDisplayData mainBadge;
@NotNull private final OffsetDateTime badgeEditingDeadline;
@Nullable private final OffsetDateTime badgeEditingDeadline;

@NotNull private final List<FursuitData> fursuits;
private final short bringingToEvent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import net.furizon.backend.feature.badge.finder.BadgeFinder;
import net.furizon.backend.infrastructure.media.ImageCodes;
import net.furizon.backend.infrastructure.media.action.DeleteMediaFromDiskAction;
import net.furizon.backend.infrastructure.security.FurizonUser;
import net.furizon.backend.infrastructure.usecase.UseCase;
import net.furizon.backend.infrastructure.web.exception.ApiException;
import org.jetbrains.annotations.NotNull;
Expand All @@ -30,7 +29,7 @@ public class DeleteBadgeUseCase implements UseCase<DeleteBadgeUseCase.Input, Boo
@Override
public @NotNull Boolean executor(@NotNull Input input) {
try {
long userId = input.user.getUserId();
long userId = input.userId;
if (input.type == BadgeType.BADGE_FURSUIT) {
Objects.requireNonNull(input.fursuitId);
fursuitChecks.assertUserHasPermissionOnFursuit(userId, input.fursuitId);
Expand All @@ -55,7 +54,7 @@ public class DeleteBadgeUseCase implements UseCase<DeleteBadgeUseCase.Input, Boo
}

public record Input(
@NotNull FurizonUser user,
long userId,
@NotNull BadgeType type,
@Nullable Long fursuitId
) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
import net.furizon.backend.infrastructure.fursuits.FursuitConfig;
import net.furizon.backend.infrastructure.pretix.model.OrderStatus;
import net.furizon.backend.infrastructure.pretix.service.PretixInformation;
import net.furizon.backend.infrastructure.security.FurizonUser;
import net.furizon.backend.infrastructure.security.GeneralResponseCodes;
import net.furizon.backend.infrastructure.usecase.UseCase;
import net.furizon.backend.infrastructure.web.exception.ApiException;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

Expand All @@ -35,10 +36,12 @@ public class GetFullInfoBadgeUseCase implements UseCase<GetFullInfoBadgeUseCase.
@Override
public @NotNull FullInfoBadgeResponse executor(@NotNull GetFullInfoBadgeUseCase.Input input) {
Event event = input.pretixInformation.getCurrentEvent();
FurizonUser user = input.user;
long userId = user.getUserId();
long userId = input.userId;

UserDisplayData userData = userFinder.getDisplayUser(userId, event);
if (userData == null) {
throw new ApiException("User not found", GeneralResponseCodes.USER_NOT_FOUND);
}
OffsetDateTime editingDeadline = badgeConfig.getEditingDeadline();

Order order = orderFinder.findOrderByUserIdEvent(userId, event, input.pretixInformation);
Expand All @@ -61,7 +64,7 @@ public class GetFullInfoBadgeUseCase implements UseCase<GetFullInfoBadgeUseCase.
}

public record Input(
@NotNull FurizonUser user,
long userId,
@NotNull PretixInformation pretixInformation
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public boolean bringFursuitToEvent(
executor.execute(
BringFursuitToEventUseCase.class,
new BringFursuitToEventUseCase.Input(
new BringFursuitToEventRequest(req.getBringToCurrentEvent(), user.getUserId()),
new BringFursuitToEventRequest(req.getBringToCurrentEvent()),
fursuitId,
user,
pretixInformation
Expand Down Expand Up @@ -182,7 +182,7 @@ public boolean bringFursuitToEvent(
executor.execute(
BringFursuitToEventUseCase.class,
new BringFursuitToEventUseCase.Input(
new BringFursuitToEventRequest(bringToCurrentEvent, user.getUserId()),
new BringFursuitToEventRequest(bringToCurrentEvent),
fursuitId,
user,
pretixInformation
Expand All @@ -193,7 +193,7 @@ public boolean bringFursuitToEvent(
executor.execute(
DeleteBadgeUseCase.class,
new DeleteBadgeUseCase.Input(
user,
user.getUserId(),
BadgeType.BADGE_FURSUIT,
fursuitId
)
Expand Down Expand Up @@ -238,6 +238,7 @@ public boolean bringFursuitToEvent(
req.getSpecies(),
req.getBringToCurrentEvent(),
req.getShowInFursuitCount(),
req.getUserId(),
user,
pretixInformation
)
Expand All @@ -262,6 +263,7 @@ public boolean bringFursuitToEvent(
@Valid @NotNull @RequestParam("species") final String species,
@RequestParam("bring-to-current-event") @NotNull final Boolean bringToCurrentEvent,
@RequestParam("show-in-fursuit-count") @NotNull final Boolean showInFursuitCount,
@RequestParam("user-id") @Nullable final Long userId,
@Nullable @RequestParam(value = "image", required = false) MultipartFile image
) {
FursuitData data = executor.execute(
Expand All @@ -271,6 +273,7 @@ public boolean bringFursuitToEvent(
species,
bringToCurrentEvent,
showInFursuitCount,
userId,
user,
pretixInformation
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@

import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.jetbrains.annotations.Nullable;

@Data
public class BringFursuitToEventRequest {
@NotNull
private final Boolean bringFursuitToCurrentEvent;

@Nullable
private final Long userId;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.furizon.backend.feature.fursuits.dto;

import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
Expand All @@ -14,4 +15,6 @@ public class FursuitDataRequest {
@NotNull private final Boolean bringToCurrentEvent;

@NotNull private final Boolean showInFursuitCount;

@Nullable private final Long userId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class BringFursuitToEventUseCase implements UseCase<BringFursuitToEventUs
PretixInformation pretixInformation = input.pretixInformation;
Event event = pretixInformation.getCurrentEvent();

long userId = generalChecks.getUserIdAndAssertPermission(input.req.getUserId(), input.user);
long userId = input.user.getUserId();
log.info("User {} is setting bringToCurrentEvent = {} on fursuit {}",
input.user.getUserId(), input.req.getBringFursuitToCurrentEvent(), input.fursuitId);
fursuitChecks.assertUserHasPermissionOnFursuit(userId, input.fursuitId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.furizon.backend.infrastructure.security.GeneralChecks;
import net.furizon.backend.infrastructure.usecase.UseCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Component;

@Slf4j
Expand All @@ -25,8 +26,8 @@ public class CreateFursuitUseCase implements UseCase<CreateFursuitUseCase.Input,

@Override
public @NotNull FursuitData executor(@NotNull Input input) {
long userId = input.user.getUserId();
log.info("User {} is creating fursuit {}", userId, input.name);
long userId = generalChecks.getUserIdAndAssertPermission(input.userId, input.user);
log.info("User {} is creating fursuit {} for user {}", input.user.getUserId(), userId, input.name);

fursuitChecks.assertUserHasNotReachedMaxBackendFursuitNo(userId);

Expand Down Expand Up @@ -69,6 +70,7 @@ public record Input(
@NotNull String species,
boolean bringToCurrentEvenet,
boolean showInFursuitCount,
@Nullable Long userId,
@NotNull FurizonUser user,
@NotNull PretixInformation pretixInformation
){}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.furizon.backend.feature.membership.dto.AddMembershipCardRequest;
import net.furizon.backend.feature.membership.dto.DeleteMembershipCardRequest;
import net.furizon.backend.feature.membership.dto.GetMembershipCardsResponse;
Expand All @@ -25,12 +26,14 @@
import net.furizon.backend.infrastructure.usecase.UseCaseExecutor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("/api/v1/membership")
@RequiredArgsConstructor
Expand Down Expand Up @@ -70,13 +73,34 @@ public boolean updateInfo(
return executor.execute(
UpdatePersonalUserInformationUseCase.class,
new UpdatePersonalUserInformationUseCase.Input(
user,
user.getUserId(),
personalUserInformation,
pretixInformation.getCurrentEvent()
)
);
}

@Operation(summary = "Update the personal user information of the specified user", description =
"This method is intended for admin use only. It also mark the information "
+ "as updated for the current event")
@PermissionRequired(permissions = {Permission.CAN_MANAGE_USER_PUBLIC_INFO})
@PostMapping("/update-personal-user-information/{userId}")
public boolean updateInfoOfUser(
@AuthenticationPrincipal @NotNull final FurizonUser user,
@PathVariable @Valid @NotNull final Long userId,
@NotNull @Valid @RequestBody final PersonalUserInformation personalUserInformation
) {
log.info("User {} is updating Personal User information of user {}", user.getUserId(), userId);
return executor.execute(
UpdatePersonalUserInformationUseCase.class,
new UpdatePersonalUserInformationUseCase.Input(
userId,
personalUserInformation,
pretixInformation.getCurrentEvent()
)
);
}

@Operation(summary = "Gets the personal information about the current logged in user")
@GetMapping("/get-personal-user-information")
public PersonalUserInformation getInfo(@AuthenticationPrincipal @NotNull final FurizonUser user) {
Expand All @@ -96,12 +120,36 @@ public boolean markInfoAsUpdated(
return executor.execute(
MarkPersonalUserInformationAsUpdatedUseCase.class,
new MarkPersonalUserInformationAsUpdatedUseCase.Input(
user,
user.getUserId(),
pretixInformation.getCurrentEvent()
)
);
}

@Operation(summary = "Resets the last information event updated for the specified user", description =
"This method is intended for admin use only. "
+ "Since it's critical to keep the personal user information updated for both "
+ "insurance and legal reasons, each different event we prompt the user to update "
+ "their information, or confirm that everything's still ok. This method is used to confirm "
+ "that the information are ok, and resets the last event where the personal user information "
+ "has been updated to the current event")
@PermissionRequired(permissions = {Permission.CAN_MANAGE_USER_PUBLIC_INFO})
@PostMapping("/mark-persona-user-information-as-updated/{userId}")
public boolean markInfoAsUpdatedOfUser(
@AuthenticationPrincipal @NotNull final FurizonUser user,
@PathVariable @Valid @NotNull final Long userId
) {
log.info("User {} is marking the personal user information of user {} as updated", user.getUserId(), userId);
return executor.execute(
MarkPersonalUserInformationAsUpdatedUseCase.class,
new MarkPersonalUserInformationAsUpdatedUseCase.Input(
userId,
pretixInformation.getCurrentEvent()
)
);
}



@Operation(summary = "Add a membership card to an user for the current event", description =
"Adds a membership card object for the specified user in the current event's year. "
Expand Down
Loading