diff --git a/.drone.yml b/.drone.yml index 8255a52..66bf451 100644 --- a/.drone.yml +++ b/.drone.yml @@ -46,7 +46,7 @@ steps: dockerfile: container/Dockerfile context: ./container repo: arminfriedl/fling - tags: latest + tags: dev when: branch: - master diff --git a/service/fling/pom.xml b/service/fling/pom.xml index 72a7885..de6f6e8 100644 --- a/service/fling/pom.xml +++ b/service/fling/pom.xml @@ -21,6 +21,7 @@ 1.64 0.11.1 ${project.parent.version} + ${project.version} @@ -102,8 +103,12 @@ - + src/main/resources true diff --git a/service/fling/src/main/java/net/friedl/fling/controller/ArtifactController.java b/service/fling/src/main/java/net/friedl/fling/controller/ArtifactController.java index 68c252d..add9f4c 100644 --- a/service/fling/src/main/java/net/friedl/fling/controller/ArtifactController.java +++ b/service/fling/src/main/java/net/friedl/fling/controller/ArtifactController.java @@ -16,6 +16,12 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import net.friedl.fling.model.dto.ArtifactDto; import net.friedl.fling.service.ArtifactService; @@ -24,6 +30,7 @@ import net.friedl.fling.service.archive.ArchiveService; @Slf4j @RestController @RequestMapping("/api/artifacts") +@Tag(name = "artifact", description = "Operations on /api/artifacts") public class ArtifactController { private ArtifactService artifactService; @@ -45,6 +52,8 @@ public class ArtifactController { artifactService.delete(id); } + @Operation(requestBody = @RequestBody( + content = @Content(schema = @Schema(type = "string", format = "binary")))) @PostMapping(path = "/{id}/data") public void uploadArtifactData(@PathVariable UUID id, HttpServletRequest request) { try { @@ -55,6 +64,12 @@ public class ArtifactController { } } + @Operation(responses = { + @ApiResponse(responseCode = "200", + content = @Content( + mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE, + schema = @Schema(type = "string", format = "binary"))) + }) @GetMapping(path = "/{id}/data") public ResponseEntity downloadArtifact(@PathVariable UUID id) { ArtifactDto artifactDto = artifactService.getById(id); diff --git a/service/fling/src/main/java/net/friedl/fling/controller/FlingController.java b/service/fling/src/main/java/net/friedl/fling/controller/FlingController.java index b1e393f..3e9c0bf 100644 --- a/service/fling/src/main/java/net/friedl/fling/controller/FlingController.java +++ b/service/fling/src/main/java/net/friedl/fling/controller/FlingController.java @@ -15,6 +15,11 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import net.friedl.fling.model.dto.ArtifactDto; import net.friedl.fling.model.dto.FlingDto; import net.friedl.fling.service.ArtifactService; @@ -23,6 +28,7 @@ import net.friedl.fling.service.archive.ArchiveService; @RestController @RequestMapping("/api/fling") +@Tag(name = "fling", description = "Operations on /api/fling") public class FlingController { private FlingService flingService; @@ -68,6 +74,12 @@ public class FlingController { flingService.delete(id); } + @Operation(responses = { + @ApiResponse(responseCode = "200", + content = @Content( + mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE, + schema = @Schema(type = "string", format = "binary"))) + }) @GetMapping(path = "/{id}/data") public ResponseEntity getFlingData(@PathVariable UUID id) { FlingDto flingDto = flingService.getById(id); diff --git a/service/fling/src/main/java/net/friedl/fling/model/dto/ArtifactDto.java b/service/fling/src/main/java/net/friedl/fling/model/dto/ArtifactDto.java index a2dba90..7f27957 100644 --- a/service/fling/src/main/java/net/friedl/fling/model/dto/ArtifactDto.java +++ b/service/fling/src/main/java/net/friedl/fling/model/dto/ArtifactDto.java @@ -4,6 +4,8 @@ import java.nio.file.Path; import java.time.Instant; import java.util.UUID; import javax.validation.constraints.NotNull; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -13,18 +15,24 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor +@Schema(name = "Artifact") public class ArtifactDto { + @Schema(accessMode = AccessMode.READ_ONLY, type = "string") @NotNull private UUID id; + @Schema(type = "string", + description = "Path of the artifact") @NotNull private Path path; - + + @Schema(type = "integer", format = "int64", + description = "Upload time in milliseconds since the unix epoch 01.01.1970 00:00:00 UTC") @Builder.Default private Instant uploadTime = Instant.now(); - private String archiveId; - + @Schema(accessMode = AccessMode.READ_ONLY, type = "boolean", + description = "Whether the artifact was successfully persisted in the archive.") @Builder.Default private Boolean archived = false; } diff --git a/service/fling/src/main/java/net/friedl/fling/model/dto/FlingDto.java b/service/fling/src/main/java/net/friedl/fling/model/dto/FlingDto.java index 90d9111..0403e0b 100644 --- a/service/fling/src/main/java/net/friedl/fling/model/dto/FlingDto.java +++ b/service/fling/src/main/java/net/friedl/fling/model/dto/FlingDto.java @@ -3,6 +3,8 @@ package net.friedl.fling.model.dto; import java.time.Instant; import java.util.UUID; import javax.validation.constraints.NotNull; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,32 +14,46 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor +@Schema(name = "Fling") public class FlingDto { + @Schema(accessMode = AccessMode.READ_ONLY, type = "string") @NotNull private UUID id; + @Schema(description = "Name of the fling") @NotNull private String name; + @Schema(type = "integer", format = "int64", + description = "Creation time in milliseconds since the unix epoch 01.01.1970 00:00:00 UTC") @NotNull @Builder.Default private Instant creationTime = Instant.now(); + @Schema(description = "Share id of the fling. Used in the share link.") @NotNull private String shareId; + @Schema(description = "Authentication code for password protecting a fling.") private String authCode; + @Schema(description = "Whether users should be redirected to fling download when accessing the " + + "fling by share id") @Builder.Default private Boolean directDownload = false; + @Schema(description = "Allow uploads to the fling by users") @Builder.Default private Boolean allowUpload = false; + @Schema(description = "Whether the fling is accessible by users via the share id") @Builder.Default private Boolean shared = true; + @Schema(description = "How many clicks are left until the fling access by share id is disallowed") private Integer expirationClicks; + @Schema(type = "integer", format = "int64", + description = "Expiration time in milliseconds since the unix epoch 01.01.1970 00:00:00 UTC") private Instant expirationTime; } diff --git a/service/fling/src/main/java/net/friedl/fling/security/FlingSecurityConfiguration.java b/service/fling/src/main/java/net/friedl/fling/security/FlingSecurityConfiguration.java index da2a866..ac75054 100644 --- a/service/fling/src/main/java/net/friedl/fling/security/FlingSecurityConfiguration.java +++ b/service/fling/src/main/java/net/friedl/fling/security/FlingSecurityConfiguration.java @@ -11,8 +11,8 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; import lombok.Data; -@Configuration @Data +@Configuration @ConfigurationProperties("fling.security") public class FlingSecurityConfiguration { private List allowedOrigins; diff --git a/service/fling/src/main/java/net/friedl/fling/security/authentication/AuthenticationController.java b/service/fling/src/main/java/net/friedl/fling/security/authentication/AuthenticationController.java index 2604a59..d9b1e30 100644 --- a/service/fling/src/main/java/net/friedl/fling/security/authentication/AuthenticationController.java +++ b/service/fling/src/main/java/net/friedl/fling/security/authentication/AuthenticationController.java @@ -5,11 +5,13 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.tags.Tag; import net.friedl.fling.security.authentication.dto.OwnerAuthDto; import net.friedl.fling.security.authentication.dto.UserAuthDto; @RestController -@RequestMapping("/api") +@RequestMapping("/api/auth") +@Tag(name = "auth", description = "Operations on /api/auth") public class AuthenticationController { private AuthenticationService authenticationService; @@ -19,12 +21,12 @@ public class AuthenticationController { this.authenticationService = authenticationService; } - @PostMapping(path = "/auth/owner") + @PostMapping(path = "/owner") public String authenticateOwner(@RequestBody OwnerAuthDto ownerAuthDto) { return authenticationService.authenticate(ownerAuthDto); } - @PostMapping("/auth/user") + @PostMapping("/user") public String authenticateUser(@RequestBody UserAuthDto userAuthDto) { return authenticationService.authenticate(userAuthDto); } diff --git a/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/OwnerAuthDto.java b/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/OwnerAuthDto.java index c4ee495..606562f 100644 --- a/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/OwnerAuthDto.java +++ b/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/OwnerAuthDto.java @@ -1,8 +1,10 @@ package net.friedl.fling.security.authentication.dto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data +@Schema(name = "OwnerAuth") public class OwnerAuthDto { private String username; private String password; diff --git a/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/UserAuthDto.java b/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/UserAuthDto.java index 51b08bc..b4a8107 100644 --- a/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/UserAuthDto.java +++ b/service/fling/src/main/java/net/friedl/fling/security/authentication/dto/UserAuthDto.java @@ -1,8 +1,10 @@ package net.friedl.fling.security.authentication.dto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data +@Schema(name = "UserAuth") public class UserAuthDto { String shareId; String code; diff --git a/service/fling/src/main/resources/META-INF/spring-configuration-metadata.json b/service/fling/src/main/resources/META-INF/spring-configuration-metadata.json index e629422..187790c 100644 --- a/service/fling/src/main/resources/META-INF/spring-configuration-metadata.json +++ b/service/fling/src/main/resources/META-INF/spring-configuration-metadata.json @@ -9,9 +9,32 @@ "name": "fling.security", "type": "net.friedl.fling.security.FlingWebSecurityConfiguration", "sourceType": "net.friedl.fling.security.FlingWebSecurityConfiguration" + }, + { + "name": "fling.api", + "type": "net.friedl.fling.controller.OpenApiConfiguration", + "sourceType": "net.friedl.fling.controller.OpenApiConfiguration" } ], "properties": [ + { + "name": "fling.api.version", + "type": "java.lang.String", + "description": "Fling API version", + "sourceType": "net.friedl.fling.controller.OpenApiConfiguration" + }, + { + "name": "fling.api.server-url", + "type": "java.lang.String", + "description": "Base URL for the fling api", + "sourceType": "net.friedl.fling.controller.OpenApiConfiguration" + }, + { + "name": "fling.api.server-description", + "type": "java.lang.String", + "description": "A description for the server to be shown in OAS", + "sourceType": "net.friedl.fling.controller.OpenApiConfiguration" + }, { "name": "fling.archive.filesystem.archive-path", "type": "java.lang.String", diff --git a/service/fling/src/main/resources/application-local.yml b/service/fling/src/main/resources/application-local.yml index acddbaa..c814456 100644 --- a/service/fling/src/main/resources/application-local.yml +++ b/service/fling/src/main/resources/application-local.yml @@ -31,4 +31,8 @@ fling: admin-user: "${FLING_ADMIN_USER:admin}" admin-password: "${FLING_ADMIN_PASSWORD:123}" signing-key: "${FLING_SIGNING_KEY:changeitchangeitchangeitchangeit}" - jwt-expiration: "${FLING_JWT_EXPIRATION:180000}" \ No newline at end of file + jwt-expiration: "${FLING_JWT_EXPIRATION:180000}" + api: + version: "0" + server-url: "http://localhost:8080" + server-description: "API server for dev" diff --git a/service/fling/src/main/resources/application.yml b/service/fling/src/main/resources/application.yml index 052a6fa..2a9c28f 100644 --- a/service/fling/src/main/resources/application.yml +++ b/service/fling/src/main/resources/application.yml @@ -1 +1,3 @@ -spring.profiles.active: "@spring.profiles.active@" # To be replaced by maven according to profile settings \ No newline at end of file + # To be replaced by maven +spring.profiles.active: "@spring.profiles.active@" +fling.api.version: "@fling.api.version@" \ No newline at end of file