From f3a01dc9bb270c3b29e1a7c919963d0497636d9b Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Wed, 2 Sep 2020 17:34:25 -0700 Subject: [PATCH] all routes for v2 users api --- .../hangar/controller/api/UsersApi.java | 22 ++--- .../controller/api/UsersApiController.java | 87 +++++++++-------- ...ProjectApiDao.java => ProjectsApiDao.java} | 2 +- .../hangar/db/dao/api/UsersApiDao.java | 80 ++++++++++++++++ .../model/generated/ProjectCompact.java | 6 ++ .../papermc/hangar/model/generated/User.java | 96 +++++++++++++++++++ .../hangar/service/api/ProjectApiService.java | 6 +- .../hangar/service/api/UserApiService.java | 42 ++++++++ .../service/project/ProjectService.java | 6 +- 9 files changed, 291 insertions(+), 56 deletions(-) rename src/main/java/io/papermc/hangar/db/dao/api/{ProjectApiDao.java => ProjectsApiDao.java} (99%) create mode 100644 src/main/java/io/papermc/hangar/db/dao/api/UsersApiDao.java create mode 100644 src/main/java/io/papermc/hangar/model/generated/User.java create mode 100644 src/main/java/io/papermc/hangar/service/api/UserApiService.java diff --git a/src/main/java/io/papermc/hangar/controller/api/UsersApi.java b/src/main/java/io/papermc/hangar/controller/api/UsersApi.java index 30718bdad..1319f3d56 100644 --- a/src/main/java/io/papermc/hangar/controller/api/UsersApi.java +++ b/src/main/java/io/papermc/hangar/controller/api/UsersApi.java @@ -1,5 +1,15 @@ package io.papermc.hangar.controller.api; +import io.papermc.hangar.db.model.UsersTable; +import io.papermc.hangar.model.generated.PaginatedCompactProjectResult; +import io.papermc.hangar.model.generated.ProjectSortingStrategy; +import io.papermc.hangar.model.generated.User; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -8,16 +18,6 @@ import org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; -import io.papermc.hangar.db.model.UsersTable; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; -import io.papermc.hangar.model.generated.PaginatedCompactProjectResult; -import io.papermc.hangar.model.generated.ProjectSortingStrategy; - @Api(value = "users", description = "the users API", tags = {"Users"}) @RequestMapping("/api/v2/") public interface UsersApi { @@ -47,7 +47,7 @@ public interface UsersApi { @RequestMapping(value = "/users/{user}", produces = {"application/json"}, method = RequestMethod.GET) - ResponseEntity showUser(@ApiParam(value = "The user to return", required = true) @PathVariable("user") String user + ResponseEntity showUser(@ApiParam(value = "The user to return", required = true) @PathVariable("user") String user ); diff --git a/src/main/java/io/papermc/hangar/controller/api/UsersApiController.java b/src/main/java/io/papermc/hangar/controller/api/UsersApiController.java index 7247b1fd0..1057a12b5 100644 --- a/src/main/java/io/papermc/hangar/controller/api/UsersApiController.java +++ b/src/main/java/io/papermc/hangar/controller/api/UsersApiController.java @@ -1,67 +1,78 @@ package io.papermc.hangar.controller.api; -import com.fasterxml.jackson.databind.ObjectMapper; - +import io.papermc.hangar.config.hangar.HangarConfig; +import io.papermc.hangar.model.ApiAuthInfo; +import io.papermc.hangar.model.Permission; +import io.papermc.hangar.model.generated.PaginatedCompactProjectResult; +import io.papermc.hangar.model.generated.Pagination; +import io.papermc.hangar.model.generated.ProjectCompact; +import io.papermc.hangar.model.generated.ProjectSortingStrategy; +import io.papermc.hangar.model.generated.User; +import io.papermc.hangar.service.api.UserApiService; +import io.papermc.hangar.util.ApiUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import javax.servlet.http.HttpServletRequest; - -import io.papermc.hangar.db.model.UsersTable; -import io.papermc.hangar.model.generated.PaginatedCompactProjectResult; -import io.papermc.hangar.model.generated.ProjectSortingStrategy; +import java.util.List; @Controller public class UsersApiController implements UsersApi { private static final Logger log = LoggerFactory.getLogger(UsersApiController.class); - private final ObjectMapper objectMapper; - - private final HttpServletRequest request; + private final HangarConfig hangarConfig; + private final ApiAuthInfo apiAuthInfo; + private final UserApiService userApiService; @Autowired - public UsersApiController(ObjectMapper objectMapper, HttpServletRequest request) { - this.objectMapper = objectMapper; - this.request = request; + public UsersApiController(HangarConfig hangarConfig, ApiAuthInfo apiAuthInfo, UserApiService userApiService) { + this.hangarConfig = hangarConfig; + this.apiAuthInfo = apiAuthInfo; + this.userApiService = userApiService; } @Override + @PreAuthorize("@authenticationService.authApiRequest(T(io.papermc.hangar.model.Permission).ViewPublicInfo, T(io.papermc.hangar.controller.util.ApiScope).forGlobal())") public ResponseEntity showStarred(String user, ProjectSortingStrategy sort, Long limit, Long offset) { - try { - return new ResponseEntity<>(objectMapper.readValue("{\n \"result\" : [ {\n \"plugin_id\" : \"plugin_id\",\n \"promoted_versions\" : [ {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n }, {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n } ],\n \"visibility\" : \"public\",\n \"stats\" : {\n \"downloads\" : 5,\n \"recent_downloads\" : 7,\n \"recent_views\" : 2,\n \"watchers\" : 3,\n \"stars\" : 9,\n \"views\" : 5\n },\n \"name\" : \"name\",\n \"namespace\" : {\n \"owner\" : \"owner\",\n \"slug\" : \"slug\"\n },\n \"category\" : \"admin_tools\"\n }, {\n \"plugin_id\" : \"plugin_id\",\n \"promoted_versions\" : [ {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n }, {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n } ],\n \"visibility\" : \"public\",\n \"stats\" : {\n \"downloads\" : 5,\n \"recent_downloads\" : 7,\n \"recent_views\" : 2,\n \"watchers\" : 3,\n \"stars\" : 9,\n \"views\" : 5\n },\n \"name\" : \"name\",\n \"namespace\" : {\n \"owner\" : \"owner\",\n \"slug\" : \"slug\"\n },\n \"category\" : \"admin_tools\"\n } ],\n \"pagination\" : {\n \"offset\" : 6,\n \"limit\" : 0,\n \"count\" : 1\n }\n}", PaginatedCompactProjectResult.class), HttpStatus.OK); // TODO Implement me - } catch (IOException e) { - log.error("Couldn't serialize response for content type application/json", e); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } + long realLimit = ApiUtil.limitOrDefault(limit, hangarConfig.projects.getInitLoad()); + long realOffset = ApiUtil.offsetOrZero(offset); + + boolean seeHidden = apiAuthInfo.getGlobalPerms().has(Permission.SeeHidden); + Long userId = apiAuthInfo.getUser() != null ? apiAuthInfo.getUser().getId() : null; + + List projectCompactList = userApiService.getStarredProjects(user, seeHidden, userId, sort, realLimit, realOffset); + long projectCount = userApiService.getStarredProjectsCount(user, seeHidden, userId); + return ResponseEntity.ok(new PaginatedCompactProjectResult().result(projectCompactList).pagination(new Pagination().limit(realLimit).offset(realOffset).count(projectCount))); } @Override - public ResponseEntity showUser(String user) { - -// try { -// return new ResponseEntity<>(objectMapper.readValue("{\n \"join_date\" : \"2000-01-23T04:56:07.000+00:00\",\n \"roles\" : [ {\n \"color\" : \"color\",\n \"name\" : \"name\",\n \"title\" : \"title\"\n }, {\n \"color\" : \"color\",\n \"name\" : \"name\",\n \"title\" : \"title\"\n } ],\n \"name\" : \"name\",\n \"created_at\" : \"2000-01-23T04:56:07.000+00:00\",\n \"tagline\" : \"tagline\"\n}", User.class), HttpStatus.OK); // TODO Implement me -// } catch (IOException e) { -// log.error("Couldn't serialize response for content type application/json", e); -// return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); -// } - - return new ResponseEntity<>(HttpStatus.OK); // TODO Implement me + @PreAuthorize("@authenticationService.authApiRequest(T(io.papermc.hangar.model.Permission).ViewPublicInfo, T(io.papermc.hangar.controller.util.ApiScope).forGlobal())") + public ResponseEntity showUser(String user) { + User userObj = userApiService.getUser(user); + if (userObj == null) { + log.error("Couldn't find a user with " + user + " name!"); + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + return ResponseEntity.ok(userObj); } @Override - public ResponseEntity showWatching(@PathVariable("user") String user, ProjectSortingStrategy sort, Long limit, Long offset) { - try { - return new ResponseEntity<>(objectMapper.readValue("{\n \"result\" : [ {\n \"plugin_id\" : \"plugin_id\",\n \"promoted_versions\" : [ {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n }, {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n } ],\n \"visibility\" : \"public\",\n \"stats\" : {\n \"downloads\" : 5,\n \"recent_downloads\" : 7,\n \"recent_views\" : 2,\n \"watchers\" : 3,\n \"stars\" : 9,\n \"views\" : 5\n },\n \"name\" : \"name\",\n \"namespace\" : {\n \"owner\" : \"owner\",\n \"slug\" : \"slug\"\n },\n \"category\" : \"admin_tools\"\n }, {\n \"plugin_id\" : \"plugin_id\",\n \"promoted_versions\" : [ {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n }, {\n \"version\" : \"version\",\n \"tags\" : [ {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n }, {\n \"data\" : \"data\",\n \"color\" : {\n \"background\" : \"background\",\n \"foreground\" : \"foreground\"\n },\n \"name\" : \"name\",\n \"display_data\" : \"display_data\",\n \"minecraft_version\" : \"minecraft_version\"\n } ]\n } ],\n \"visibility\" : \"public\",\n \"stats\" : {\n \"downloads\" : 5,\n \"recent_downloads\" : 7,\n \"recent_views\" : 2,\n \"watchers\" : 3,\n \"stars\" : 9,\n \"views\" : 5\n },\n \"name\" : \"name\",\n \"namespace\" : {\n \"owner\" : \"owner\",\n \"slug\" : \"slug\"\n },\n \"category\" : \"admin_tools\"\n } ],\n \"pagination\" : {\n \"offset\" : 6,\n \"limit\" : 0,\n \"count\" : 1\n }\n}", PaginatedCompactProjectResult.class), HttpStatus.OK); // TODO Implement me - } catch (IOException e) { - log.error("Couldn't serialize response for content type application/json", e); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } + @PreAuthorize("@authenticationService.authApiRequest(T(io.papermc.hangar.model.Permission).ViewPublicInfo, T(io.papermc.hangar.controller.util.ApiScope).forGlobal())") + public ResponseEntity showWatching(String user, ProjectSortingStrategy sort, Long limit, Long offset) { + long realLimit = ApiUtil.limitOrDefault(limit, hangarConfig.projects.getInitLoad()); + long realOffset = ApiUtil.offsetOrZero(offset); + + boolean seeHidden = apiAuthInfo.getGlobalPerms().has(Permission.SeeHidden); + Long userId = apiAuthInfo.getUser() != null ? apiAuthInfo.getUser().getId() : null; + + List projectCompactList = userApiService.getWatchedProjects(user, seeHidden, userId, sort, realLimit, realOffset); + long projectCount = userApiService.getWatchedProjectsCount(user, seeHidden, userId); + return ResponseEntity.ok(new PaginatedCompactProjectResult().result(projectCompactList).pagination(new Pagination().limit(realLimit).offset(realOffset).count(projectCount))); } } diff --git a/src/main/java/io/papermc/hangar/db/dao/api/ProjectApiDao.java b/src/main/java/io/papermc/hangar/db/dao/api/ProjectsApiDao.java similarity index 99% rename from src/main/java/io/papermc/hangar/db/dao/api/ProjectApiDao.java rename to src/main/java/io/papermc/hangar/db/dao/api/ProjectsApiDao.java index 5b2a2bf60..c2ba2ccb2 100644 --- a/src/main/java/io/papermc/hangar/db/dao/api/ProjectApiDao.java +++ b/src/main/java/io/papermc/hangar/db/dao/api/ProjectsApiDao.java @@ -20,7 +20,7 @@ import java.util.Map; @Repository @RegisterBeanMapper(Project.class) -public interface ProjectApiDao { +public interface ProjectsApiDao { @UseStringTemplateEngine @SqlQuery("SELECT p.created_at," + diff --git a/src/main/java/io/papermc/hangar/db/dao/api/UsersApiDao.java b/src/main/java/io/papermc/hangar/db/dao/api/UsersApiDao.java new file mode 100644 index 000000000..5c760a69e --- /dev/null +++ b/src/main/java/io/papermc/hangar/db/dao/api/UsersApiDao.java @@ -0,0 +1,80 @@ +package io.papermc.hangar.db.dao.api; + +import io.papermc.hangar.db.mappers.PromotedVersionMapper; +import io.papermc.hangar.model.generated.ProjectCompact; +import io.papermc.hangar.model.generated.User; +import org.jdbi.v3.sqlobject.config.RegisterBeanMapper; +import org.jdbi.v3.sqlobject.config.RegisterColumnMapper; +import org.jdbi.v3.sqlobject.customizer.Define; +import org.jdbi.v3.sqlobject.statement.SqlQuery; +import org.jdbi.v3.stringtemplate4.UseStringTemplateEngine; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface UsersApiDao { + + @RegisterBeanMapper(User.class) + @SqlQuery("SELECT u.created_at, u.name, u.tagline, u.join_date, array_agg(r.name) roles " + + " FROM users u" + + " JOIN user_global_roles ugr ON u.id = ugr.user_id" + + " JOIN roles r ON ugr.role_id = r.id" + + " WHERE u.name = :name" + + " GROUP BY u.id") + User userQuery(String name); + + @UseStringTemplateEngine + @RegisterBeanMapper(ProjectCompact.class) + @RegisterColumnMapper(PromotedVersionMapper.class) + @SqlQuery("SELECT p.plugin_id," + + " p.name," + + " p.owner_name \"owner\"," + + " p.slug," + + " p.promoted_versions," + + " p.views," + + " p.downloads," + + " p.recent_views," + + " p.recent_downloads," + + " p.stars," + + " p.watchers," + + " p.category," + + " p.visibility" + + " FROM users u " + + " JOIN project_watchers pw ON u.id = pw.user_id" + + " JOIN home_projects p ON pw.project_id = p.id" + + " WHERE " + + " (p.visibility = 0 OR p.visibility = 1" + + " OR ( = ANY(p.project_members) AND p.visibility != 4)) AND" + + " u.name = :user" + + " ORDER BY :sortOrder LIMIT :limit OFFSET :offset") + List watchersQuery(String user, @Define boolean canSeeHidden, @Define Long userId, String sortOrder, Long limit, long offset); + + @UseStringTemplateEngine + @RegisterBeanMapper(ProjectCompact.class) + @RegisterColumnMapper(PromotedVersionMapper.class) + @SqlQuery("SELECT p.plugin_id," + + " p.name," + + " p.owner_name \"owner\"," + + " p.slug," + + " p.promoted_versions," + + " p.views," + + " p.downloads," + + " p.recent_views," + + " p.recent_downloads," + + " p.stars," + + " p.watchers," + + " p.category," + + " p.visibility" + + " FROM users u " + + " JOIN project_stars ps ON u.id = ps.user_id" + + " JOIN home_projects p ON ps.project_id = p.id" + + " WHERE " + + " (p.visibility = 0 OR p.visibility = 1" + + " OR ( = ANY(p.project_members) AND p.visibility != 4)) AND" + + " u.name = :user" + + " ORDER BY :sortOrder LIMIT :limit OFFSET :offset") + List starredQuery(String user, @Define boolean canSeeHidden, @Define Long userId, String sortOrder, Long limit, long offset); + + +} diff --git a/src/main/java/io/papermc/hangar/model/generated/ProjectCompact.java b/src/main/java/io/papermc/hangar/model/generated/ProjectCompact.java index cf35e9d70..04a10e28c 100644 --- a/src/main/java/io/papermc/hangar/model/generated/ProjectCompact.java +++ b/src/main/java/io/papermc/hangar/model/generated/ProjectCompact.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; +import org.jdbi.v3.core.enums.EnumByOrdinal; +import org.jdbi.v3.core.mapper.Nested; import org.springframework.validation.annotation.Validated; import java.util.ArrayList; @@ -139,6 +141,7 @@ public class ProjectCompact { return namespace; } + @Nested public void setNamespace(ProjectNamespace namespace) { this.namespace = namespace; } @@ -187,6 +190,7 @@ public class ProjectCompact { return stats; } + @Nested public void setStats(ProjectStatsAll stats) { this.stats = stats; } @@ -209,6 +213,7 @@ public class ProjectCompact { return category; } + @EnumByOrdinal public void setCategory(Category category) { this.category = category; } @@ -230,6 +235,7 @@ public class ProjectCompact { return visibility; } + @EnumByOrdinal public void setVisibility(VisibilityEnum visibility) { this.visibility = visibility; } diff --git a/src/main/java/io/papermc/hangar/model/generated/User.java b/src/main/java/io/papermc/hangar/model/generated/User.java new file mode 100644 index 000000000..4615e0f64 --- /dev/null +++ b/src/main/java/io/papermc/hangar/model/generated/User.java @@ -0,0 +1,96 @@ +package io.papermc.hangar.model.generated; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.papermc.hangar.model.Role; +import io.swagger.annotations.ApiModelProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; + +@Validated +public class User { + @JsonProperty("createdAt") + private OffsetDateTime createdAt = null; + + @JsonProperty("name") + private String name = null; + + @JsonProperty("tagline") + private String tagline = null; + + @JsonProperty("joinDate") + private OffsetDateTime joinDate = null; + + @JsonProperty("roles") + private List roles = new ArrayList<>(); + + @ApiModelProperty(required = true) + @NotNull + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + @ApiModelProperty(required = true) + @NotNull + @Valid + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @ApiModelProperty() + @Nullable + @Valid + public String getTagline() { + return tagline; + } + + public void setTagline(String tagline) { + this.tagline = tagline; + } + + @ApiModelProperty() + @Nullable + @Valid + public OffsetDateTime getJoinDate() { + return joinDate; + } + + public void setJoinDate(OffsetDateTime joinDate) { + this.joinDate = joinDate; + } + + @ApiModelProperty(required = true) + @NotNull + @Valid + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + @Override + public String toString() { + return "User{" + + "createdAt=" + createdAt + + ", name='" + name + '\'' + + ", tagline='" + tagline + '\'' + + ", joinDate=" + joinDate + + ", roles=" + roles + + '}'; + } +} diff --git a/src/main/java/io/papermc/hangar/service/api/ProjectApiService.java b/src/main/java/io/papermc/hangar/service/api/ProjectApiService.java index c9f776ad3..11810a164 100644 --- a/src/main/java/io/papermc/hangar/service/api/ProjectApiService.java +++ b/src/main/java/io/papermc/hangar/service/api/ProjectApiService.java @@ -1,7 +1,7 @@ package io.papermc.hangar.service.api; import io.papermc.hangar.db.dao.HangarDao; -import io.papermc.hangar.db.dao.api.ProjectApiDao; +import io.papermc.hangar.db.dao.api.ProjectsApiDao; import io.papermc.hangar.model.generated.ProjectMember; import io.papermc.hangar.model.generated.ProjectStatsDay; import org.springframework.stereotype.Service; @@ -13,9 +13,9 @@ import java.util.Map; @Service public class ProjectApiService { - private final HangarDao projectApiDao; + private final HangarDao projectApiDao; - public ProjectApiService(HangarDao projectApiDao) { + public ProjectApiService(HangarDao projectApiDao) { this.projectApiDao = projectApiDao; } diff --git a/src/main/java/io/papermc/hangar/service/api/UserApiService.java b/src/main/java/io/papermc/hangar/service/api/UserApiService.java new file mode 100644 index 000000000..417fa4d2f --- /dev/null +++ b/src/main/java/io/papermc/hangar/service/api/UserApiService.java @@ -0,0 +1,42 @@ +package io.papermc.hangar.service.api; + +import io.papermc.hangar.db.dao.HangarDao; +import io.papermc.hangar.db.dao.api.UsersApiDao; +import io.papermc.hangar.db.model.UsersTable; +import io.papermc.hangar.model.generated.PaginatedCompactProjectResult; +import io.papermc.hangar.model.generated.ProjectCompact; +import io.papermc.hangar.model.generated.ProjectSortingStrategy; +import io.papermc.hangar.model.generated.User; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class UserApiService { + + private final HangarDao usersApiDao; + + public UserApiService(HangarDao usersApiDao) { + this.usersApiDao = usersApiDao; + } + + public User getUser(String name) { + return usersApiDao.get().userQuery(name); + } + + public List getWatchedProjects(String user, boolean seeHidden, Long userId, ProjectSortingStrategy strategy, long limit, long offset) { + return usersApiDao.get().watchersQuery(user, seeHidden, userId, strategy.getSql(), limit, offset); + } + + public long getWatchedProjectsCount(String user, boolean seeHidden, Long userId) { + return usersApiDao.get().watchersQuery(user, seeHidden, userId, ProjectSortingStrategy.VIEWS.getSql(), null, 0).size(); + } + + public List getStarredProjects(String user, boolean seeHidden, Long userId, ProjectSortingStrategy strategy, long limit, long offset) { + return usersApiDao.get().starredQuery(user, seeHidden, userId, strategy.getSql(), limit, offset); + } + + public long getStarredProjectsCount(String user, boolean seeHidden, Long userId) { + return usersApiDao.get().starredQuery(user, seeHidden, userId, ProjectSortingStrategy.VIEWS.getSql(), null, 0).size(); + } +} diff --git a/src/main/java/io/papermc/hangar/service/project/ProjectService.java b/src/main/java/io/papermc/hangar/service/project/ProjectService.java index 2e01cfd75..b51446dec 100644 --- a/src/main/java/io/papermc/hangar/service/project/ProjectService.java +++ b/src/main/java/io/papermc/hangar/service/project/ProjectService.java @@ -6,7 +6,7 @@ import io.papermc.hangar.db.dao.HangarDao; import io.papermc.hangar.db.dao.ProjectDao; import io.papermc.hangar.db.dao.UserDao; import io.papermc.hangar.db.dao.ProjectViewDao; -import io.papermc.hangar.db.dao.api.ProjectApiDao; +import io.papermc.hangar.db.dao.api.ProjectsApiDao; import io.papermc.hangar.db.model.ProjectVersionsTable; import io.papermc.hangar.db.model.ProjectVisibilityChangesTable; import io.papermc.hangar.db.model.ProjectsTable; @@ -49,7 +49,7 @@ public class ProjectService { private final HangarDao projectDao; private final HangarDao userDao; private final HangarDao visibilityDao; - private final HangarDao projectApiDao; + private final HangarDao projectApiDao; private final HangarDao projectViewDao; private final HangarDao generalDao; private final UserService userService; @@ -57,7 +57,7 @@ public class ProjectService { private final ProjectFiles projectFiles; @Autowired - public ProjectService(HangarConfig hangarConfig, HangarDao projectDao, HangarDao userDao, HangarDao visibilityDao, HangarDao projectApiDao, HangarDao projectViewDao, HangarDao generalDao, ProjectFiles projectFiles, UserService userService, FlagService flagService) { + public ProjectService(HangarConfig hangarConfig, HangarDao projectDao, HangarDao userDao, HangarDao visibilityDao, HangarDao projectApiDao, HangarDao projectViewDao, HangarDao generalDao, ProjectFiles projectFiles, UserService userService, FlagService flagService) { this.hangarConfig = hangarConfig; this.projectDao = projectDao; this.userDao = userDao;