Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Commit

Permalink
BE-#0: Update event invitation link flow for authenticated users
Browse files Browse the repository at this point in the history
  • Loading branch information
Drumber committed Apr 24, 2024
1 parent 8888413 commit c67cb5d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

@Service
Expand Down Expand Up @@ -95,20 +96,6 @@ public Event updateEvent(AuthenticatedPrincipal principal, String eventId, Event
return eventRepository.save(newEvent);
}

@PreAuthorize("hasRole('USER')")
public Event addParticipantToEvent(AuthenticatedPrincipal principal, String invitationLink) {
Optional<Event> event = eventRepository.findByInvitationLink(invitationLink);
return event.map(presentEvent -> {
Optional<User> user = this.userService.findUserFromPrincipal(principal);
return user.map(presentUser -> {
presentEvent.addParticipant(presentUser.getId());
return eventRepository.save(presentEvent);
})
.orElseThrow(() -> new EntityNotFoundException("User not found"));
})
.orElseThrow(() -> new EntityNotFoundException("Event not found"));
}

@PreAuthorize("hasRole('USER')")
public Event generateInvitationLink(AuthenticatedPrincipal principal, String eventId) {
Event event = getEventIfUserIsParticipant(principal, eventId);
Expand All @@ -117,10 +104,13 @@ public Event generateInvitationLink(AuthenticatedPrincipal principal, String eve
}

@PreAuthorize("hasRole('GUEST')")
public Optional<String> findRouteFromInvitationLink(AuthenticatedPrincipal principal, String invitationLink) {
public Optional<String> openEventFromInvitationLink(AuthenticatedPrincipal principal, String invitationLink) {
Optional<Event> event = findEventByInvitationLink(invitationLink);
if (event.isPresent() && principal instanceof GuestAuthenticationPrincipal guestPrincipal) {
guestPrincipal.grantAccessToEvent(event.get().getId());
} else if (event.isPresent() && principal instanceof OAuth2User) {
// add user as participant
event = event.map(e -> addUserToParticipantsIfNotParticipating(principal, e));
}
return event.map(presentEvent -> env.getProperty("frontend.url") + "/event/" + presentEvent.getId());
}
Expand All @@ -144,4 +134,11 @@ private Event getEventIfUserIsParticipant(AuthenticatedPrincipal principal, Stri
private Optional<Event> findEventByInvitationLink(String invitationLink) {
return eventRepository.findByInvitationLink(invitationLink);
}

private Event addUserToParticipantsIfNotParticipating(AuthenticatedPrincipal principal, Event event) {
User user = userService.getUserByPrincipal(principal);
if (event.getParticipantIds().contains(user.getId())) return event;
event.addParticipant(user.getId());
return eventRepository.save(event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public String getInvitationLink(
@AuthenticationPrincipal AuthenticatedPrincipal principal,
HttpServletResponse httpServletResponse,
@PathVariable String invitationLink) {
Optional<String> locationUrl = eventService.findRouteFromInvitationLink(principal, invitationLink);
Optional<String> locationUrl = eventService.openEventFromInvitationLink(principal, invitationLink);
if (locationUrl.isPresent()) {
httpServletResponse.setHeader("Location", locationUrl.get());
httpServletResponse.setStatus(HttpServletResponse.SC_FOUND);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.security.access.AccessDeniedException;
Expand Down Expand Up @@ -313,45 +314,6 @@ void shouldUpdateEventIfUserIsParticipant() {
assertThat(updatedEvent.getName()).isEqualTo(command.getName());
}

@Test
@WithMockGuestUser
void shouldNotAddParticipantIfUserIsGuest() {
// given
AuthenticatedPrincipal principal = (AuthenticatedPrincipal)
SecurityContextHolder.getContext().getAuthentication().getPrincipal();

// when
// then
assertThatThrownBy(() -> eventService.addParticipantToEvent(principal, "123"))
.isInstanceOf(AccessDeniedException.class);
}

@Test
@WithMockOAuth2User
void shouldAddParticipantIfIsUser() {
// given
AuthenticatedPrincipal principal = (AuthenticatedPrincipal)
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user = User.builder().id("test").build();
final String invitationLink = "123";
Event event = Event.builder()
.id("1")
.participantIds(new ArrayList<>())
.invitationLink(invitationLink)
.build();

when(userService.findUserFromPrincipal(any())).thenReturn(Optional.of(user));
when(eventRepository.findByInvitationLink(eq(invitationLink))).thenReturn(Optional.of(event));
when(eventRepository.save(any())).thenAnswer(args -> args.getArgument(0));

// when
Event updatedEvent = eventService.addParticipantToEvent(principal, invitationLink);

// then
assertThat(updatedEvent).isNotNull();
assertThat(updatedEvent.getParticipantIds()).containsExactly(user.getId());
}

@Test
@WithMockOAuth2User
void shouldNotGenerateInvitationLinkIfUserIsNotParticipant() {
Expand Down Expand Up @@ -399,7 +361,7 @@ void shouldGenerateInvitationLinkIfUserIsParticipant() {

@Test
@WithMockGuestUser
void shouldFindRouteFromInvitationLinkIfUserIsGuest() {
void shouldOpenEventFromInvitationLinkIfUserIsGuest() {
// given
AuthenticatedPrincipal principal = (AuthenticatedPrincipal)
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Expand All @@ -409,11 +371,38 @@ void shouldFindRouteFromInvitationLinkIfUserIsGuest() {
when(eventRepository.findByInvitationLink(eq(invitationLink))).thenReturn(Optional.of(event));

// when
Optional<String> route = eventService.findRouteFromInvitationLink(principal, invitationLink);
Optional<String> route = eventService.openEventFromInvitationLink(principal, invitationLink);

// then
assertThat(route).isPresent().asString().isNotBlank();
assertThat(((GuestAuthenticationPrincipal) principal).getGrantedEventIds())
.containsExactly(event.getId());
}

@Test
@WithMockOAuth2User
void shouldOpenEventFromInvitationLinkIfIsUser() {
// given
AuthenticatedPrincipal principal = (AuthenticatedPrincipal)
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user = User.builder().id("test").build();
String invitationLink = "123";
Event event = Event.builder()
.id("1")
.invitationLink(invitationLink)
.participantIds(new ArrayList<>())
.build();

ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);
when(userService.getUserByPrincipal(any())).thenReturn(user);
when(eventRepository.findByInvitationLink(eq(invitationLink))).thenReturn(Optional.of(event));
when(eventRepository.save(eventCaptor.capture())).thenAnswer(args -> args.getArgument(0));

// when
Optional<String> route = eventService.openEventFromInvitationLink(principal, invitationLink);

// then
assertThat(route).isPresent().asString().isNotBlank();
assertThat(eventCaptor.getValue().getParticipantIds()).contains(user.getId());
}
}

0 comments on commit c67cb5d

Please sign in to comment.