From d5173e162f72d107c61b132d50c40e53487e8fe8 Mon Sep 17 00:00:00 2001 From: kevin Date: Sun, 19 Apr 2026 19:25:27 -0400 Subject: [PATCH] Add Server endpoints + shoebill --- backend/build.gradle | 5 +- .../backend/BackendApplication.java | 6 +- .../backend/config/ShoebillConfiguration.java | 14 ++++ .../backend/controllers/ServerController.java | 67 ++++++++++++++++ .../controllers/UserProfileController.java | 19 ++--- .../backend/datamodels/channel/Channel.java | 4 +- .../datamodels/channel/ChannelType.java | 2 +- .../backend/datamodels/message/Message.java | 10 ++- .../server/GetAllServersResponse.java | 10 +++ .../datamodels/server/GetServerResponse.java | 12 +++ .../datamodels/server/PostServerRequest.java | 14 ++++ .../datamodels/server/PostServerResponse.java | 12 +++ .../backend/datamodels/server/Server.java | 6 +- .../GetAllUserProfilesResponse.java | 2 +- .../userprofile/GetUserProfileResponse.java | 2 +- .../userprofile/PostUserProfileRequest.java | 2 +- .../userprofile/PostUserProfileResponse.java | 2 +- .../datamodels/userprofile/UserProfile.java | 2 +- .../repositories/ChannelRepository.java | 4 +- .../repositories/MessageRepository.java | 4 +- .../repositories/ServerRepository.java | 4 +- .../repositories/UserProfileRepository.java | 4 +- .../backend/services/ServerService.java | 79 +++++++++++++++++++ .../backend/services/UserProfileService.java | 18 ++--- .../exceptions/BadRequestException.java | 2 +- .../exceptions/NotFoundException.java | 2 +- .../src/main/resources/application.properties | 3 +- 27 files changed, 263 insertions(+), 48 deletions(-) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/BackendApplication.java (53%) create mode 100644 backend/src/main/java/net/kpuig/shoebill/backend/config/ShoebillConfiguration.java create mode 100644 backend/src/main/java/net/kpuig/shoebill/backend/controllers/ServerController.java rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/controllers/UserProfileController.java (87%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/channel/Channel.java (80%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/channel/ChannelType.java (54%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/message/Message.java (65%) create mode 100644 backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetAllServersResponse.java create mode 100644 backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetServerResponse.java create mode 100644 backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerRequest.java create mode 100644 backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerResponse.java rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/server/Server.java (77%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/userprofile/GetAllUserProfilesResponse.java (71%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/userprofile/GetUserProfileResponse.java (66%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/userprofile/PostUserProfileRequest.java (72%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/userprofile/PostUserProfileResponse.java (66%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/datamodels/userprofile/UserProfile.java (85%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/repositories/ChannelRepository.java (65%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/repositories/MessageRepository.java (65%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/repositories/ServerRepository.java (65%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/repositories/UserProfileRepository.java (71%) create mode 100644 backend/src/main/java/net/kpuig/shoebill/backend/services/ServerService.java rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/services/UserProfileService.java (75%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/services/exceptions/BadRequestException.java (71%) rename backend/src/main/java/net/kpuig/{concord => shoebill}/backend/services/exceptions/NotFoundException.java (71%) diff --git a/backend/build.gradle b/backend/build.gradle index e0d33d7..136d23d 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -4,9 +4,9 @@ plugins { id 'io.spring.dependency-management' version '1.1.7' } -group = 'net.kpuig.concord' +group = 'net.kpuig.shoebill' version = '0.0.1-SNAPSHOT' -description = 'Concord REST Server' +description = 'Shoebill REST Server' java { toolchain { @@ -30,6 +30,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-webmvc' implementation 'org.springframework.boot:spring-boot-starter-websocket' implementation 'org.springframework.boot:spring-boot-h2console' + implementation 'org.springframework.boot:spring-boot-autoconfigure-processor' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3' //implementation 'org.springframework.boot:spring-boot-starter-security' //implementation 'org.springframework.boot:spring-boot-starter-security-oauth2-resource-server' diff --git a/backend/src/main/java/net/kpuig/concord/backend/BackendApplication.java b/backend/src/main/java/net/kpuig/shoebill/backend/BackendApplication.java similarity index 53% rename from backend/src/main/java/net/kpuig/concord/backend/BackendApplication.java rename to backend/src/main/java/net/kpuig/shoebill/backend/BackendApplication.java index 5632a77..5fcdd83 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/BackendApplication.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/BackendApplication.java @@ -1,8 +1,12 @@ -package net.kpuig.concord.backend; +package net.kpuig.shoebill.backend; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import net.kpuig.shoebill.backend.config.ShoebillConfiguration; + +@EnableConfigurationProperties(ShoebillConfiguration.class) @SpringBootApplication public class BackendApplication { diff --git a/backend/src/main/java/net/kpuig/shoebill/backend/config/ShoebillConfiguration.java b/backend/src/main/java/net/kpuig/shoebill/backend/config/ShoebillConfiguration.java new file mode 100644 index 0000000..50097bf --- /dev/null +++ b/backend/src/main/java/net/kpuig/shoebill/backend/config/ShoebillConfiguration.java @@ -0,0 +1,14 @@ +package net.kpuig.shoebill.backend.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.bind.DefaultValue; +import org.springframework.validation.annotation.Validated; + +@ConfigurationProperties(prefix = "shoebill") +@Validated +public record ShoebillConfiguration ( + @DefaultValue("false") + boolean relativePicturesOnly +) { + +} diff --git a/backend/src/main/java/net/kpuig/shoebill/backend/controllers/ServerController.java b/backend/src/main/java/net/kpuig/shoebill/backend/controllers/ServerController.java new file mode 100644 index 0000000..94b7b27 --- /dev/null +++ b/backend/src/main/java/net/kpuig/shoebill/backend/controllers/ServerController.java @@ -0,0 +1,67 @@ +package net.kpuig.shoebill.backend.controllers; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; +import net.kpuig.shoebill.backend.datamodels.server.GetAllServersResponse; +import net.kpuig.shoebill.backend.datamodels.server.GetServerResponse; +import net.kpuig.shoebill.backend.datamodels.server.PostServerRequest; +import net.kpuig.shoebill.backend.datamodels.server.PostServerResponse; +import net.kpuig.shoebill.backend.services.ServerService; +import net.kpuig.shoebill.backend.services.exceptions.BadRequestException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + + + +@RestController +@RequestMapping("/api/server") +public class ServerController { + @Autowired private ServerService serverService; + + @Operation(summary = "Get all servers", description = "Retrieves a list of all servers") + @ApiResponse(responseCode = "200", description = "Servers retrieved") + @GetMapping("/") + public ResponseEntity getAllServers() { + return ResponseEntity.ok(serverService.getAllServers()); + } + + @Operation(summary = "Get server by ID", description = "Retrieves a server by its ID") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "Server retrieved"), + @ApiResponse(responseCode = "404", description = "Server not found") + }) + @GetMapping("") + public ResponseEntity getServerById(@RequestParam(name = "id", required = false) Long id) { + try { + return ResponseEntity.ok(serverService.getServerById(id)); + } catch (Exception e) { + return ResponseEntity.notFound().build(); + } + } + + @Operation(summary = "Create a new server", description = "Creates a new server with the provided name and image") + @ApiResponses({ + @ApiResponse(responseCode = "201", description = "Server created"), + @ApiResponse(responseCode = "400", description = "Invalid request") + }) + @PostMapping("/") + public ResponseEntity postMethodName(@Valid @RequestBody PostServerRequest request) { + try { + var response = serverService.createServer(request); + return ResponseEntity.ok(response); + } catch (BadRequestException e) { + return ResponseEntity.badRequest().build(); + } + } + +} diff --git a/backend/src/main/java/net/kpuig/concord/backend/controllers/UserProfileController.java b/backend/src/main/java/net/kpuig/shoebill/backend/controllers/UserProfileController.java similarity index 87% rename from backend/src/main/java/net/kpuig/concord/backend/controllers/UserProfileController.java rename to backend/src/main/java/net/kpuig/shoebill/backend/controllers/UserProfileController.java index 1365f37..99d7880 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/controllers/UserProfileController.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/controllers/UserProfileController.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.controllers; +package net.kpuig.shoebill.backend.controllers; import java.net.URI; @@ -17,18 +17,15 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import jakarta.validation.Valid; -import net.kpuig.concord.backend.datamodels.userprofile.GetAllUserProfilesResponse; -import net.kpuig.concord.backend.datamodels.userprofile.GetUserProfileResponse; -import net.kpuig.concord.backend.datamodels.userprofile.PostUserProfileRequest; -import net.kpuig.concord.backend.datamodels.userprofile.PostUserProfileResponse; -import net.kpuig.concord.backend.services.UserProfileService; -import net.kpuig.concord.backend.services.exceptions.BadRequestException; - - - +import net.kpuig.shoebill.backend.datamodels.userprofile.GetAllUserProfilesResponse; +import net.kpuig.shoebill.backend.datamodels.userprofile.GetUserProfileResponse; +import net.kpuig.shoebill.backend.datamodels.userprofile.PostUserProfileRequest; +import net.kpuig.shoebill.backend.datamodels.userprofile.PostUserProfileResponse; +import net.kpuig.shoebill.backend.services.UserProfileService; +import net.kpuig.shoebill.backend.services.exceptions.BadRequestException; @RestController -@RequestMapping("/user-profile") +@RequestMapping("/api/user-profile") public class UserProfileController { @Autowired private UserProfileService userProfileService; diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/channel/Channel.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/channel/Channel.java similarity index 80% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/channel/Channel.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/channel/Channel.java index c9e5e2e..e022113 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/channel/Channel.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/channel/Channel.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.datamodels.channel; +package net.kpuig.shoebill.backend.datamodels.channel; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -6,7 +6,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; import lombok.Data; -import net.kpuig.concord.backend.datamodels.server.Server; +import net.kpuig.shoebill.backend.datamodels.server.Server; @Data @Entity(name = "channel") diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/channel/ChannelType.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/channel/ChannelType.java similarity index 54% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/channel/ChannelType.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/channel/ChannelType.java index 3811224..9827c8d 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/channel/ChannelType.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/channel/ChannelType.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.datamodels.channel; +package net.kpuig.shoebill.backend.datamodels.channel; public enum ChannelType { TEXT_CHANNEL, diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/message/Message.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/message/Message.java similarity index 65% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/message/Message.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/message/Message.java index 9ebe032..4a7de14 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/message/Message.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/message/Message.java @@ -1,13 +1,14 @@ -package net.kpuig.concord.backend.datamodels.message; +package net.kpuig.shoebill.backend.datamodels.message; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; import lombok.Data; -import net.kpuig.concord.backend.datamodels.channel.Channel; -import net.kpuig.concord.backend.datamodels.userprofile.UserProfile; +import net.kpuig.shoebill.backend.datamodels.channel.Channel; +import net.kpuig.shoebill.backend.datamodels.userprofile.UserProfile; @Data @Entity(name = "message") @@ -20,6 +21,9 @@ public class Message { private Long timestamp; + @OneToOne + private Message replyTo; + @ManyToOne private UserProfile userProfile; diff --git a/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetAllServersResponse.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetAllServersResponse.java new file mode 100644 index 0000000..b29f9c0 --- /dev/null +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetAllServersResponse.java @@ -0,0 +1,10 @@ +package net.kpuig.shoebill.backend.datamodels.server; + +import java.util.List; + +import lombok.Data; + +@Data +public class GetAllServersResponse { + private List servers; +} diff --git a/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetServerResponse.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetServerResponse.java new file mode 100644 index 0000000..6575842 --- /dev/null +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/GetServerResponse.java @@ -0,0 +1,12 @@ +package net.kpuig.shoebill.backend.datamodels.server; + +import java.net.URI; + +import lombok.Data; + +@Data +public class GetServerResponse { + private Long id; + private String name; + private URI image; +} diff --git a/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerRequest.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerRequest.java new file mode 100644 index 0000000..bebb987 --- /dev/null +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerRequest.java @@ -0,0 +1,14 @@ +package net.kpuig.shoebill.backend.datamodels.server; + +import java.net.URI; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +@Data +public class PostServerRequest { + @NotBlank + private String name; + + private URI image; +} diff --git a/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerResponse.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerResponse.java new file mode 100644 index 0000000..e5aadfe --- /dev/null +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/PostServerResponse.java @@ -0,0 +1,12 @@ +package net.kpuig.shoebill.backend.datamodels.server; + +import java.net.URI; + +import lombok.Data; + +@Data +public class PostServerResponse { + private Long id; + private String name; + private URI image; +} diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/server/Server.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/Server.java similarity index 77% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/server/Server.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/Server.java index 3e61626..03f6871 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/server/Server.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/server/Server.java @@ -1,6 +1,6 @@ -package net.kpuig.concord.backend.datamodels.server; +package net.kpuig.shoebill.backend.datamodels.server; -import java.net.URL; +import java.net.URI; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -17,5 +17,5 @@ public class Server { private String name; - private URL image; + private URI image; } diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/GetAllUserProfilesResponse.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/GetAllUserProfilesResponse.java similarity index 71% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/GetAllUserProfilesResponse.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/GetAllUserProfilesResponse.java index 85ee79f..ee06565 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/GetAllUserProfilesResponse.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/GetAllUserProfilesResponse.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.datamodels.userprofile; +package net.kpuig.shoebill.backend.datamodels.userprofile; import java.util.List; diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/GetUserProfileResponse.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/GetUserProfileResponse.java similarity index 66% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/GetUserProfileResponse.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/GetUserProfileResponse.java index f81a07d..58f9b3c 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/GetUserProfileResponse.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/GetUserProfileResponse.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.datamodels.userprofile; +package net.kpuig.shoebill.backend.datamodels.userprofile; import lombok.Data; diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/PostUserProfileRequest.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/PostUserProfileRequest.java similarity index 72% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/PostUserProfileRequest.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/PostUserProfileRequest.java index 2fce0f3..979e360 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/PostUserProfileRequest.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/PostUserProfileRequest.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.datamodels.userprofile; +package net.kpuig.shoebill.backend.datamodels.userprofile; import jakarta.validation.constraints.NotBlank; import lombok.Data; diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/PostUserProfileResponse.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/PostUserProfileResponse.java similarity index 66% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/PostUserProfileResponse.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/PostUserProfileResponse.java index e6e3629..2bfa942 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/PostUserProfileResponse.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/PostUserProfileResponse.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.datamodels.userprofile; +package net.kpuig.shoebill.backend.datamodels.userprofile; import lombok.Data; diff --git a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/UserProfile.java b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/UserProfile.java similarity index 85% rename from backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/UserProfile.java rename to backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/UserProfile.java index f45bead..da680e4 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/datamodels/userprofile/UserProfile.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/datamodels/userprofile/UserProfile.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.datamodels.userprofile; +package net.kpuig.shoebill.backend.datamodels.userprofile; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/backend/src/main/java/net/kpuig/concord/backend/repositories/ChannelRepository.java b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/ChannelRepository.java similarity index 65% rename from backend/src/main/java/net/kpuig/concord/backend/repositories/ChannelRepository.java rename to backend/src/main/java/net/kpuig/shoebill/backend/repositories/ChannelRepository.java index 582be30..ae66385 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/repositories/ChannelRepository.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/ChannelRepository.java @@ -1,9 +1,9 @@ -package net.kpuig.concord.backend.repositories; +package net.kpuig.shoebill.backend.repositories; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import net.kpuig.concord.backend.datamodels.channel.Channel; +import net.kpuig.shoebill.backend.datamodels.channel.Channel; @Repository public interface ChannelRepository extends JpaRepository { diff --git a/backend/src/main/java/net/kpuig/concord/backend/repositories/MessageRepository.java b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/MessageRepository.java similarity index 65% rename from backend/src/main/java/net/kpuig/concord/backend/repositories/MessageRepository.java rename to backend/src/main/java/net/kpuig/shoebill/backend/repositories/MessageRepository.java index a03bb3a..4739319 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/repositories/MessageRepository.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/MessageRepository.java @@ -1,9 +1,9 @@ -package net.kpuig.concord.backend.repositories; +package net.kpuig.shoebill.backend.repositories; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import net.kpuig.concord.backend.datamodels.message.Message; +import net.kpuig.shoebill.backend.datamodels.message.Message; @Repository public interface MessageRepository extends JpaRepository { diff --git a/backend/src/main/java/net/kpuig/concord/backend/repositories/ServerRepository.java b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/ServerRepository.java similarity index 65% rename from backend/src/main/java/net/kpuig/concord/backend/repositories/ServerRepository.java rename to backend/src/main/java/net/kpuig/shoebill/backend/repositories/ServerRepository.java index 1cf4b9a..0ed48f7 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/repositories/ServerRepository.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/ServerRepository.java @@ -1,9 +1,9 @@ -package net.kpuig.concord.backend.repositories; +package net.kpuig.shoebill.backend.repositories; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import net.kpuig.concord.backend.datamodels.server.Server; +import net.kpuig.shoebill.backend.datamodels.server.Server; @Repository public interface ServerRepository extends JpaRepository { diff --git a/backend/src/main/java/net/kpuig/concord/backend/repositories/UserProfileRepository.java b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/UserProfileRepository.java similarity index 71% rename from backend/src/main/java/net/kpuig/concord/backend/repositories/UserProfileRepository.java rename to backend/src/main/java/net/kpuig/shoebill/backend/repositories/UserProfileRepository.java index dccc824..21da66a 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/repositories/UserProfileRepository.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/repositories/UserProfileRepository.java @@ -1,11 +1,11 @@ -package net.kpuig.concord.backend.repositories; +package net.kpuig.shoebill.backend.repositories; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import net.kpuig.concord.backend.datamodels.userprofile.UserProfile; +import net.kpuig.shoebill.backend.datamodels.userprofile.UserProfile; @Repository public interface UserProfileRepository extends JpaRepository { diff --git a/backend/src/main/java/net/kpuig/shoebill/backend/services/ServerService.java b/backend/src/main/java/net/kpuig/shoebill/backend/services/ServerService.java new file mode 100644 index 0000000..99e1afc --- /dev/null +++ b/backend/src/main/java/net/kpuig/shoebill/backend/services/ServerService.java @@ -0,0 +1,79 @@ +package net.kpuig.shoebill.backend.services; + +import java.net.URI; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import net.kpuig.shoebill.backend.config.ShoebillConfiguration; +import net.kpuig.shoebill.backend.datamodels.server.GetAllServersResponse; +import net.kpuig.shoebill.backend.datamodels.server.GetServerResponse; +import net.kpuig.shoebill.backend.datamodels.server.PostServerRequest; +import net.kpuig.shoebill.backend.datamodels.server.PostServerResponse; +import net.kpuig.shoebill.backend.datamodels.server.Server; +import net.kpuig.shoebill.backend.repositories.ServerRepository; +import net.kpuig.shoebill.backend.services.exceptions.BadRequestException; +import net.kpuig.shoebill.backend.services.exceptions.NotFoundException; + +@Service +public class ServerService { + @Autowired private ShoebillConfiguration shoebillConfiguration; + @Autowired private ServerRepository serverRepository; + + public GetAllServersResponse getAllServers() { + GetAllServersResponse response = new GetAllServersResponse(); + response.setServers(serverRepository.findAll().stream().map(server -> { + GetServerResponse serverResponse = new GetServerResponse(); + serverResponse.setId(server.getId()); + serverResponse.setName(server.getName()); + serverResponse.setImage(server.getImage()); + return serverResponse; + }).toList()); + return response; + } + + public GetServerResponse getServerById(Long id) { + GetServerResponse response = new GetServerResponse(); + serverRepository.findById(id).ifPresentOrElse(server -> { + response.setId(server.getId()); + response.setName(server.getName()); + response.setImage(server.getImage()); + }, () -> { + throw new NotFoundException("Server not found with id: " + id); + }); + return response; + } + + public PostServerResponse createServer(PostServerRequest request) { + Server server = new Server(); + server.setName(request.getName()); + server.setImage(request.getImage()); + + try { + server = serverRepository.save(server); + var uri = new URI(request.getImage().toString()); + + // Make sure it's either relative with no injections or a complete HTTP/HTTPS URL + if (uri.isAbsolute()) { + if (shoebillConfiguration.relativePicturesOnly()) { + throw new BadRequestException("Only relative image URLs are allowed"); + } + if (!uri.getScheme().equals("http") && !uri.getScheme().equals("https")) { + throw new BadRequestException("Image URL must be HTTP or HTTPS"); + } + } else { + if (request.getImage().toString().contains("..") || request.getImage().toString().contains("//") || request.getImage().toString().contains("\\")) { + throw new BadRequestException("Relative image URL cannot contain '..', '//', or '\\'"); + } + } + } catch (Exception e) { + throw new BadRequestException("Invalid image URL"); + } + + PostServerResponse response = new PostServerResponse(); + response.setId(server.getId()); + response.setName(server.getName()); + response.setImage(server.getImage()); + return response; + } +} diff --git a/backend/src/main/java/net/kpuig/concord/backend/services/UserProfileService.java b/backend/src/main/java/net/kpuig/shoebill/backend/services/UserProfileService.java similarity index 75% rename from backend/src/main/java/net/kpuig/concord/backend/services/UserProfileService.java rename to backend/src/main/java/net/kpuig/shoebill/backend/services/UserProfileService.java index 8820977..394dd6a 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/services/UserProfileService.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/services/UserProfileService.java @@ -1,14 +1,14 @@ -package net.kpuig.concord.backend.services; +package net.kpuig.shoebill.backend.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import net.kpuig.concord.backend.datamodels.userprofile.GetAllUserProfilesResponse; -import net.kpuig.concord.backend.datamodels.userprofile.GetUserProfileResponse; -import net.kpuig.concord.backend.datamodels.userprofile.PostUserProfileResponse; -import net.kpuig.concord.backend.datamodels.userprofile.UserProfile; -import net.kpuig.concord.backend.repositories.UserProfileRepository; -import net.kpuig.concord.backend.services.exceptions.BadRequestException; +import net.kpuig.shoebill.backend.datamodels.userprofile.GetAllUserProfilesResponse; +import net.kpuig.shoebill.backend.datamodels.userprofile.GetUserProfileResponse; +import net.kpuig.shoebill.backend.datamodels.userprofile.PostUserProfileResponse; +import net.kpuig.shoebill.backend.datamodels.userprofile.UserProfile; +import net.kpuig.shoebill.backend.repositories.UserProfileRepository; +import net.kpuig.shoebill.backend.services.exceptions.BadRequestException; @Service public class UserProfileService { @@ -32,7 +32,7 @@ public class UserProfileService { response.setId(userProfile.getId()); response.setUsername(userProfile.getUsername()); }, () -> { - throw new net.kpuig.concord.backend.services.exceptions.NotFoundException("User profile not found"); + throw new net.kpuig.shoebill.backend.services.exceptions.NotFoundException("User profile not found"); }); return response; } @@ -43,7 +43,7 @@ public class UserProfileService { response.setId(userProfile.getId()); response.setUsername(userProfile.getUsername()); }, () -> { - throw new net.kpuig.concord.backend.services.exceptions.NotFoundException("User profile not found"); + throw new net.kpuig.shoebill.backend.services.exceptions.NotFoundException("User profile not found"); }); return response; } diff --git a/backend/src/main/java/net/kpuig/concord/backend/services/exceptions/BadRequestException.java b/backend/src/main/java/net/kpuig/shoebill/backend/services/exceptions/BadRequestException.java similarity index 71% rename from backend/src/main/java/net/kpuig/concord/backend/services/exceptions/BadRequestException.java rename to backend/src/main/java/net/kpuig/shoebill/backend/services/exceptions/BadRequestException.java index 3027c14..d6ce748 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/services/exceptions/BadRequestException.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/services/exceptions/BadRequestException.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.services.exceptions; +package net.kpuig.shoebill.backend.services.exceptions; public class BadRequestException extends RuntimeException { public BadRequestException(String message) { diff --git a/backend/src/main/java/net/kpuig/concord/backend/services/exceptions/NotFoundException.java b/backend/src/main/java/net/kpuig/shoebill/backend/services/exceptions/NotFoundException.java similarity index 71% rename from backend/src/main/java/net/kpuig/concord/backend/services/exceptions/NotFoundException.java rename to backend/src/main/java/net/kpuig/shoebill/backend/services/exceptions/NotFoundException.java index fb77384..14754bf 100644 --- a/backend/src/main/java/net/kpuig/concord/backend/services/exceptions/NotFoundException.java +++ b/backend/src/main/java/net/kpuig/shoebill/backend/services/exceptions/NotFoundException.java @@ -1,4 +1,4 @@ -package net.kpuig.concord.backend.services.exceptions; +package net.kpuig.shoebill.backend.services.exceptions; public class NotFoundException extends RuntimeException { public NotFoundException(String message) { diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 6b6a321..0a45475 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -12,4 +12,5 @@ server.port=8080 springdoc.api-docs.enabled=true springdoc.api-docs.path=/v3/api-docs springdoc.swagger-ui.enabled=true -springdoc.swagger-ui.path=/swag \ No newline at end of file +springdoc.swagger-ui.path=/swag +shoebill.relative-pictures-only=true \ No newline at end of file