dont use HangarUser for user's other than the logged in one

This commit is contained in:
Jake Potrebic 2021-03-20 19:01:08 -07:00
parent dfb8189c39
commit 1f846da7c5
No known key found for this signature in database
GPG Key ID: 7C58557EC9C421F8
9 changed files with 52 additions and 71 deletions

View File

@ -1,41 +1,6 @@
package io.papermc.hangar.controller;
import io.papermc.hangar.config.hangar.HangarConfig;
import io.papermc.hangar.security.HangarAuthenticationToken;
import io.papermc.hangar.security.HangarPrincipal;
import io.papermc.hangar.service.internal.UserActionLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.server.ResponseStatusException;
import io.papermc.hangar.service.HangarService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract class HangarController {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
protected HangarConfig hangarConfig;
@Autowired
protected HttpServletRequest request;
@Autowired
protected HttpServletResponse response;
@Autowired
protected UserActionLogService userActionLogService;
protected final HangarPrincipal getHangarPrincipal() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof HangarAuthenticationToken)) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "No authentication principal found");
}
return (HangarPrincipal) authentication.getPrincipal();
}
public abstract class HangarController extends HangarService {
}

View File

@ -128,6 +128,7 @@ public class BackendDataController {
@GetMapping("/projectRoles")
public ResponseEntity<List<ProjectRole>> getAssignableProjectRoles() {
// TODO only assignable roles here
return ResponseEntity.ok(/*ProjectRole.getAssignableRoles()*/ Arrays.asList(ProjectRole.getValues().clone()));
}

View File

@ -7,6 +7,7 @@ import io.papermc.hangar.db.customtypes.LoggedActionType;
import io.papermc.hangar.db.customtypes.LoggedActionType.UserContext;
import io.papermc.hangar.exceptions.HangarApiException;
import io.papermc.hangar.model.common.NamedPermission;
import io.papermc.hangar.model.common.Permission;
import io.papermc.hangar.model.common.roles.Role;
import io.papermc.hangar.model.db.UserTable;
import io.papermc.hangar.model.db.roles.ExtendedRoleTable;
@ -20,9 +21,9 @@ import io.papermc.hangar.service.api.UsersApiService;
import io.papermc.hangar.service.internal.roles.MemberService;
import io.papermc.hangar.service.internal.roles.MemberService.OrganizationMemberService;
import io.papermc.hangar.service.internal.roles.MemberService.ProjectMemberService;
import io.papermc.hangar.service.internal.roles.OrganizationRoleService;
import io.papermc.hangar.service.internal.roles.ProjectRoleService;
import io.papermc.hangar.service.internal.roles.RoleService;
import io.papermc.hangar.service.internal.roles.RoleService.OrganizationRoleService;
import io.papermc.hangar.service.internal.roles.RoleService.ProjectRoleService;
import io.papermc.hangar.service.internal.users.InviteService;
import io.papermc.hangar.service.internal.users.NotificationService;
import io.papermc.hangar.service.internal.users.UserService;
@ -76,35 +77,34 @@ public class HangarUserController extends HangarController {
return ResponseEntity.ok(usersApiService.getUser(hangarAuthenticationToken.getName(), HangarUser.class));
}
@GetMapping("/users/{user}")
public ResponseEntity<HangarUser> getUser(@PathVariable("user") String userName) {
return ResponseEntity.ok(usersApiService.getUser(userName, HangarUser.class));
}
@Unlocked
@ResponseStatus(HttpStatus.OK)
@PermissionRequired(perms = NamedPermission.EDIT_OWN_USER_SETTINGS)
@PostMapping(path = "/users/{userId}/settings/tagline", consumes = MediaType.APPLICATION_JSON_VALUE)
public void saveTagline(@PathVariable long userId, @Valid @RequestBody StringContent content) {
UserTable userTable = userService.getUserTable(userId);
@PostMapping(path = "/users/{userName}/settings/tagline", consumes = MediaType.APPLICATION_JSON_VALUE)
public void saveTagline(@PathVariable String userName, @Valid @RequestBody StringContent content) {
UserTable userTable = userService.getUserTable(userName);
if (userTable == null) {
throw new HangarApiException(HttpStatus.NOT_FOUND);
}
if (content.getContent().length() > hangarConfig.user.getMaxTaglineLen()) {
// TODO what perm to check here
if (userTable.getId() != getHangarPrincipal().getId() && !getGlobalPermissions().has(Permission.ManualValueChanges)) {
throw new HangarApiException(HttpStatus.FORBIDDEN);
}
if (content.getContent().length() > config.user.getMaxTaglineLen()) {
throw new HangarApiException(HttpStatus.BAD_REQUEST, "author.error.invalidTagline");
}
String oldTagline = userTable.getTagline() == null ? "" : userTable.getTagline();
userTable.setTagline(content.getContent());
userService.updateUser(userTable);
userActionLogService.user(LoggedActionType.USER_TAGLINE_CHANGED.with(UserContext.of(userId)), userTable.getTagline(), oldTagline);
userActionLogService.user(LoggedActionType.USER_TAGLINE_CHANGED.with(UserContext.of(userTable.getId())), userTable.getTagline(), oldTagline);
}
@Unlocked
@ResponseStatus(HttpStatus.OK)
@PermissionRequired(perms = NamedPermission.EDIT_OWN_USER_SETTINGS)
@PostMapping("/users/{userId}/settings/resetTagline")
public void resetTagline(@PathVariable long userId) {
UserTable userTable = userService.getUserTable(userId);
@PostMapping("/users/{userName}/settings/resetTagline")
public void resetTagline(@PathVariable String userName) {
UserTable userTable = userService.getUserTable(userName);
if (userTable == null) {
throw new HangarApiException(HttpStatus.NOT_FOUND);
}
@ -114,7 +114,7 @@ public class HangarUserController extends HangarController {
}
userTable.setTagline(null);
userService.updateUser(userTable);
userActionLogService.user(LoggedActionType.USER_TAGLINE_CHANGED.with(UserContext.of(userId)), "", oldTagline);
userActionLogService.user(LoggedActionType.USER_TAGLINE_CHANGED.with(UserContext.of(userTable.getId())), "", oldTagline);
}
@GetMapping("/notifications")

View File

@ -50,8 +50,8 @@ public class LoginController extends HangarController {
@GetMapping(path = "/login", params = "returnUrl")
public Object loginFromFrontend(@RequestParam(defaultValue = Routes.Paths.SHOW_HOME) String returnUrl, RedirectAttributes attributes) {
if (hangarConfig.fakeUser.isEnabled()) {
hangarConfig.checkDev();
if (config.fakeUser.isEnabled()) {
config.checkDev();
UserTable fakeUser = authenticationService.loginAsFakeUser();
tokenService.createTokenForUser(fakeUser);
@ -59,7 +59,7 @@ public class LoginController extends HangarController {
} else {
try {
response.addCookie(new Cookie("url", returnUrl));
return redirectToSso(ssoService.getLoginUrl(hangarConfig.getBaseUrl() + "/login"), attributes);
return redirectToSso(ssoService.getLoginUrl(config.getBaseUrl() + "/login"), attributes);
} catch (HangarException e) {
AlertUtil.showAlert(attributes, AlertUtil.AlertType.ERROR, e.getMessageKey(), e.getArgs());
return Routes.SHOW_HOME.getRedirect();
@ -131,7 +131,7 @@ public class LoginController extends HangarController {
@PostMapping("/verify")
public ModelAndView verify(@RequestParam String returnPath, RedirectAttributes attributes) {
try {
return redirectToSso(ssoService.getVerifyUrl(hangarConfig.getBaseUrl() + returnPath), attributes);
return redirectToSso(ssoService.getVerifyUrl(config.getBaseUrl() + returnPath), attributes);
} catch (HangarException e) {
AlertUtil.showAlert(attributes, AlertUtil.AlertType.ERROR, e.getMessageKey(), e.getArgs());
return Routes.SHOW_HOME.getRedirect();
@ -142,7 +142,7 @@ public class LoginController extends HangarController {
public ModelAndView logout(HttpSession session) {
// TODO flash
session.invalidate();
return Routes.getRedirectToUrl(hangarConfig.getAuthUrl() + "/accounts/logout/");
return Routes.getRedirectToUrl(config.getAuthUrl() + "/accounts/logout/");
}
@GetMapping("/signup")
@ -158,9 +158,9 @@ public class LoginController extends HangarController {
private ModelAndView redirectBackOnSuccessfulLogin(String url, UserTable user) {
if (!url.startsWith("http")) {
if (url.startsWith("/")) {
url = hangarConfig.getBaseUrl() + url;
url = config.getBaseUrl() + url;
} else {
url = hangarConfig.getBaseUrl() + "/" + url;
url = config.getBaseUrl() + "/" + url;
}
}
// response.addCookie(CookieUtils.builder(HangarAuthenticationFilter.AUTH_NAME, tokenService.expiring()));
@ -168,7 +168,7 @@ public class LoginController extends HangarController {
}
private ModelAndView redirectToSso(URLWithNonce urlWithNonce, RedirectAttributes attributes) {
if (!hangarConfig.sso.isEnabled()) {
if (!config.sso.isEnabled()) {
AlertUtil.showAlert(attributes, AlertUtil.AlertType.ERROR, "error.noLogin");
return Routes.SHOW_HOME.getRedirect();
}

View File

@ -34,6 +34,10 @@ public interface NotificationsDAO {
" AND n.read IS FALSE")
long getUnreadNotificationCount(long userId);
@SqlQuery("SELECT (SELECT count(*) FROM user_project_roles upr WHERE upr.user_id = :userId AND upr.accepted IS FALSE) + " +
" (SELECT count(*) FROM user_organization_roles uor WHERE uor.user_id = :userId AND uor.accepted IS FALSE) AS count")
long getUnansweredInvites(long userId);
@SqlQuery("SELECT count(*)" +
" FROM project_flags pf" +
" WHERE pf.resolved IS FALSE")

View File

@ -70,13 +70,15 @@ public class HangarUser extends User implements Identified {
public static class HeaderData {
private final Permission globalPermission;
private final long unreadNotifications;
private final long unansweredInvites;
private final long unresolvedFlags;
private final long projectApprovals;
private final long reviewQueueCount;
public HeaderData(Permission globalPermission, long unreadNotifications, long unresolvedFlags, long projectApprovals, long reviewQueueCount) {
public HeaderData(Permission globalPermission, long unreadNotifications, long unansweredInvites, long unresolvedFlags, long projectApprovals, long reviewQueueCount) {
this.globalPermission = globalPermission;
this.unreadNotifications = unreadNotifications;
this.unansweredInvites = unansweredInvites;
this.unresolvedFlags = unresolvedFlags;
this.projectApprovals = projectApprovals;
this.reviewQueueCount = reviewQueueCount;
@ -90,6 +92,10 @@ public class HangarUser extends User implements Identified {
return unreadNotifications;
}
public long getUnansweredInvites() {
return unansweredInvites;
}
public long getUnresolvedFlags() {
return unresolvedFlags;
}
@ -107,6 +113,7 @@ public class HangarUser extends User implements Identified {
return "HeaderData{" +
"globalPermission=" + globalPermission +
", unreadNotifications=" + unreadNotifications +
", unansweredInvites=" + unansweredInvites +
", unresolvedFlags=" + unresolvedFlags +
", projectApprovals=" + projectApprovals +
", reviewQueueCount=" + reviewQueueCount +

View File

@ -27,7 +27,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
@Service
@ -134,12 +133,14 @@ public class UsersApiService extends HangarService {
public HangarUser supplyHeaderData(HangarUser hangarUser) {
Permission globalPermission = permissionService.getGlobalPermissions(hangarUser.getId());
long unreadNotifs = notificationsDAO.getUnreadNotificationCount(hangarUser.getId());
long unansweredInvites = notificationsDAO.getUnansweredInvites(hangarUser.getId());
long unresolvedFlags = globalPermission.has(Permission.ModNotesAndFlags) ? notificationsDAO.getUnresolvedFlagsCount() : 0;
long projectApprovals = globalPermission.has(Permission.ModNotesAndFlags.add(Permission.SeeHidden)) ? notificationsDAO.getProjectApprovalsCount() : 0;
long reviewQueueCount = globalPermission.has(Permission.Reviewer) ? notificationsDAO.getReviewQueueCount() : 0;
hangarUser.setHeaderData(new HeaderData(
globalPermission,
unreadNotifs,
unansweredInvites,
unresolvedFlags,
projectApprovals,
reviewQueueCount

View File

@ -5,15 +5,16 @@ import io.papermc.hangar.db.dao.internal.HangarNotificationsDAO;
import io.papermc.hangar.db.dao.internal.table.NotificationsDAO;
import io.papermc.hangar.db.dao.internal.table.projects.ProjectsDAO;
import io.papermc.hangar.model.common.Permission;
import io.papermc.hangar.model.common.roles.ProjectRole;
import io.papermc.hangar.model.db.NotificationTable;
import io.papermc.hangar.model.db.UserTable;
import io.papermc.hangar.model.db.projects.ProjectTable;
import io.papermc.hangar.model.db.versions.ProjectVersionTable;
import io.papermc.hangar.model.internal.api.requests.EditMembersForm.Member;
import io.papermc.hangar.model.internal.user.notifications.HangarNotification;
import io.papermc.hangar.model.internal.user.notifications.NotificationType;
import io.papermc.hangar.service.HangarService;
import io.papermc.hangar.service.PermissionService;
import io.papermc.hangar.service.internal.projects.ProjectService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@ -25,14 +26,12 @@ public class NotificationService extends HangarService {
private final NotificationsDAO notificationsDAO;
private final HangarNotificationsDAO hangarNotificationsDAO;
private final ProjectsDAO projectsDAO;
private final ProjectService projectService;
private final PermissionService permissionService;
public NotificationService(HangarDao<NotificationsDAO> notificationsDAO, HangarDao<HangarNotificationsDAO> hangarNotificationsDAO, HangarDao<ProjectsDAO> projectsDAO, ProjectService projectService, PermissionService permissionService) {
public NotificationService(HangarDao<NotificationsDAO> notificationsDAO, HangarDao<HangarNotificationsDAO> hangarNotificationsDAO, HangarDao<ProjectsDAO> projectsDAO, PermissionService permissionService) {
this.notificationsDAO = notificationsDAO.get();
this.hangarNotificationsDAO = hangarNotificationsDAO.get();
this.projectsDAO = projectsDAO.get();
this.projectService = projectService;
this.permissionService = permissionService;
}
@ -44,15 +43,15 @@ public class NotificationService extends HangarService {
return notificationsDAO.markAsRead(notificationId, getHangarPrincipal().getId());
}
public void notifyUsersNewVersion(ProjectTable projectTable, ProjectVersionTable projectVersionTable) {
public void notifyUsersNewVersion(ProjectTable projectTable, ProjectVersionTable projectVersionTable, List<UserTable> projectWatchers) {
List<NotificationTable> notificationTables = new ArrayList<>();
for (UserTable projectWatcher : projectService.getProjectWatchers(projectTable.getId())) {
for (UserTable projectWatcher : projectWatchers) {
notificationTables.add(new NotificationTable(
projectWatcher.getId(),
NotificationType.NEW_PROJECT_VERSION,
projectTable.getOwnerName() + "/" + projectTable.getSlug(),
projectTable.getId(),
new String[]{"notification.project.newVersion", projectTable.getName(), projectVersionTable.getVersionString()})
new String[]{"notifications.project.newVersion", projectTable.getName(), projectVersionTable.getVersionString()})
);
}
notificationsDAO.insert(notificationTables);
@ -74,4 +73,8 @@ public class NotificationService extends HangarService {
});
notificationsDAO.insert(notificationTables);
}
public void notifyNewProjectMember(Member<ProjectRole> member, long userId, ProjectTable projectTable) {
notificationsDAO.insert(new NotificationTable(userId, NotificationType.PROJECT_INVITE, null, projectTable.getId(), new String[]{"notification.project.invite", member.getRole().getTitle(), projectTable.getName()}));
}
}

View File

@ -242,7 +242,7 @@ public class VersionFactory extends HangarService {
versionTagService.addUnstableTag(projectVersionTable.getId());
}
notificationService.notifyUsersNewVersion(projectTable, projectVersionTable);
notificationService.notifyUsersNewVersion(projectTable, projectVersionTable, projectService.getProjectWatchers(projectTable.getId()));
if (tmpVersionJar != null) {
for (Platform platform : pendingVersion.getPlatformDependencies().keySet()) {