Skip to content

Commit

Permalink
Profile pages are now public
Browse files Browse the repository at this point in the history
Invalid userIds now throw exception while trying to access profile page
Allowed gifs as avatars
Fixed discord id size in mentions
Reworded event participation
  • Loading branch information
Alf-Melmac committed Sep 9, 2021
1 parent f7788f3 commit 3d586a9
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.webalf.slotbot.controller.website;

import de.webalf.slotbot.controller.NotificationSettingsController;
import de.webalf.slotbot.exception.ResourceNotFoundException;
import de.webalf.slotbot.model.User;
import de.webalf.slotbot.service.NotificationSettingsService;
import de.webalf.slotbot.service.UserService;
Expand All @@ -15,9 +16,12 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import java.util.stream.Collectors;

import static de.webalf.slotbot.service.external.DiscordApiService.isUnknownUser;
import static de.webalf.slotbot.util.StringUtils.onlyNumbers;
import static de.webalf.slotbot.util.permissions.ApplicationPermissionHelper.HAS_ROLE_EVERYONE;
import static de.webalf.slotbot.util.permissions.PermissionHelper.getLoggedInUserId;
import static de.webalf.slotbot.util.permissions.PermissionHelper.isLoggedInUser;
Expand All @@ -37,19 +41,23 @@ public class ProfileWebController {
private final NotificationSettingsService notificationSettingsService;

@GetMapping("{userId}")
@PreAuthorize(HAS_ROLE_EVERYONE)
public ModelAndView getProfile(@PathVariable(value = "userId") String userId) {
if ("me".equals(userId)) {
return new ModelAndView("redirect:" + linkTo(methodOn(ProfileWebController.class).getProfile(getLoggedInUserId())).toUri());
return new ModelAndView("redirect:" + linkTo(methodOn(ProfileWebController.class).getProfileRedirect()).toUri());
} else if (!onlyNumbers(userId)) {
throw new ResourceNotFoundException("Profile request with invalid id " + userId);
}

ModelAndView mav = new ModelAndView("profile");
mav.addObject("startUrl", linkTo(methodOn(StartWebController.class).getStart()).toUri().toString());

final GuildMember guildMember = discordApiService.getGuildMemberWithUser(userId);
final User user = userService.find(Long.parseLong(userId));
if (isUnknownUser(guildMember)) {
throw new ResourceNotFoundException("Unknown discord user " + userId);
}
mav.addObject("user", guildMember);
mav.addObject("roles", "@" + discordApiService.getRoles(guildMember.getRoles()).stream().map(Role::getName).collect(Collectors.joining(", @")));
final User user = userService.find(Long.parseLong(userId));
mav.addObject("participatedEventsCount", userService.getParticipatedEventsCount(user));

final boolean ownProfile = isLoggedInUser(userId);
Expand All @@ -62,4 +70,12 @@ public ModelAndView getProfile(@PathVariable(value = "userId") String userId) {

return mav;
}

@GetMapping("/redirect/me")
@PreAuthorize(HAS_ROLE_EVERYONE)
public RedirectView getProfileRedirect() {
RedirectView redirectView = new RedirectView();
redirectView.setUrl(linkTo(methodOn(ProfileWebController.class).getProfile(getLoggedInUserId())).toUri().toString());
return redirectView;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public String getName(String userId) {
return guildMember.getNick();
}

private static final String UNKNOWN_USER_NAME = "Unbekannter Nutzer";
/**
* @see <a href="https://discord.com/developers/docs/resources/user#get-user" target"_top">https://discord.com/developers/docs/resources/user#get-user</a>
*/
Expand All @@ -77,12 +78,16 @@ private User getUser(String userId) {
.onErrorResume(error -> {
log.error("Failed to get user {}", userId, error);
final User errorUser = new User();
errorUser.setUsername("Unbekannter Nutzer");
errorUser.setUsername(UNKNOWN_USER_NAME);
return Mono.just(errorUser);
})
.block();
}

public static boolean isUnknownUser(@NonNull GuildMember member) {
return UNKNOWN_USER_NAME.equals(member.getUser().getUsername());
}

private boolean wait = false;
private long waitUntil;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public static PrivateChannel getPrivateChannel(@NonNull JDA jda, long userId) {
}

public static String getAvatarUrl(@NotBlank String id, String avatar, @NotBlank String discriminator) {
return avatar != null ? "https://cdn.discordapp.com/avatars/" + id + "/" + avatar + ".png" : getDefaultAvatarUrl(Short.parseShort(discriminator));
if (avatar == null) {
return getDefaultAvatarUrl(Short.parseShort(discriminator));
}
return "https://cdn.discordapp.com/avatars/" + id + "/" + avatar + (avatar.startsWith("a_") ? ".gif" : ".png");
}

private static String getDefaultAvatarUrl(short discriminator) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/de/webalf/slotbot/util/bot/MentionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
*/
@UtilityClass
public final class MentionUtils {
private static final Pattern USER_MENTION = Pattern.compile("^<@!?\\d{17,18}>$");
private static final Pattern CHANNEL_MENTION = Pattern.compile("^<#?\\d{17,18}>$");
private static final Pattern USER_MENTION = Pattern.compile("^<@!?\\d{17,19}>$");
private static final Pattern CHANNEL_MENTION = Pattern.compile("^<#?\\d{17,19}>$");

public static boolean isUserMention(String arg) {
return USER_MENTION.matcher(arg).matches();
Expand Down
11 changes: 6 additions & 5 deletions src/main/resources/templates/profile.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="de" xmlns:th="http://www.thymeleaf.org">
<html lang="de" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta th:replace="fragments/general.html :: head('Profil')"/>
<meta property="og:title" th:content="${user.getNick()}">
<meta property="og:image" th:content="${user.getAvatarUrl()}">
<meta property="og:description" th:content="${participatedEventsCount + ' Teilnahmen'}">
<meta property="og:description" th:content="${participatedEventsCount + ' Event-Teilnahmen'}">

<link rel="stylesheet" th:href="@{/assets/css/sizes.css}">
<link rel="stylesheet" th:href="@{/assets/css/positions.css}">
Expand All @@ -25,11 +25,11 @@
alt="Discord avatar"/>
</div>
<h4 class="mb-2" th:text="${user.getNick()}"></h4>
<p class="text-muted" th:text="${roles}"></p>
<p sec:authorize="isAuthenticated()" class="text-muted" th:text="${roles}"></p>
<div class="d-flex justify-content-center mt-5">
<div>
<p class="h5" th:text="${participatedEventsCount}">?</p>
<p class="text-muted mb-0">Teilgenommene Events</p>
<p class="text-muted mb-0">Event-Teilnahmen</p>
</div>
</div>
</div>
Expand Down Expand Up @@ -95,7 +95,8 @@ <h3 class="mt-4">Globale Benachrichtigungseinstellungen</h3>

<div th:if="${ownProfile}" th:replace="fragments/toasts.html"></div>

<footer th:insert="fragments/general.html :: footer"></footer>
<footer sec:authorize="isAuthenticated()" th:insert="fragments/general.html :: footer"></footer>
<footer sec:authorize="isAnonymous()" th:insert="fragments/general.html :: footer" class="fixed-bottom"></footer>

<script th:replace="fragments/scripts.html :: jqueryANDpopperANDbootstrap"></script>
<script th:inline="javascript">
Expand Down

0 comments on commit 3d586a9

Please sign in to comment.