diff --git a/src/main/java/dev/dinauer/maven/Dev.java b/src/main/java/dev/dinauer/maven/Dev.java index d9bbcfb..a34c2ad 100644 --- a/src/main/java/dev/dinauer/maven/Dev.java +++ b/src/main/java/dev/dinauer/maven/Dev.java @@ -26,19 +26,23 @@ import org.jspecify.annotations.NonNull; import java.io.IOException; import java.io.InputStream; +import java.security.SecureRandom; import java.time.LocalDate; import java.time.ZonedDateTime; +import java.util.List; import java.util.Objects; +import java.util.Random; import java.util.UUID; @ApplicationScoped @IfBuildProfile("dev") -public class Dev +public class Dev implements SecurityIdentityAugmentor { private static final BCrypt.Hasher HASHER = BCrypt.withDefaults(); @Inject TokenRepo tokenRepo; + @Inject MavenService mavenService; @@ -59,6 +63,8 @@ public class Dev uploadRelease_02(); uploadSnapshot_01(); uploadSnapshot_02(); + uploadSnapshot_03(); + uploadParent_01(); } private void uploadRelease_01() throws IOException @@ -89,8 +95,25 @@ public class Dev mavenService.upload("/org/postgresql/postgresql/42.7.9-SNAPSHOT/postgresql-42.7.9-20250419.133456-1.pom", readFile("/jar/postgresql-42.7.9.pom")); } + private void uploadSnapshot_03() throws IOException + { + mavenService.upload("/org/postgresql/postgresql/42.7.10-SNAPSHOT/postgresql-42.7.10-20250419.123456-1.jar", readFile("/jar/postgresql-42.7.9.jar")); + mavenService.upload("/org/postgresql/postgresql/42.7.10-SNAPSHOT/postgresql-42.7.10-20250419.123456-1.pom", readFile("/jar/postgresql-42.7.9.pom")); + } + private byte[] readFile(String path) throws IOException { return Objects.requireNonNull(getClass().getResourceAsStream(path)).readAllBytes(); } + + private void uploadParent_01() throws IOException + { + mavenService.upload("/dev/dinauer/maven-parent/1.0.0/maven-parent-1.0.0.pom", readFile("/jar/postgresql-42.7.9.pom")); + } + + @Override + public Uni augment(SecurityIdentity identity, AuthenticationRequestContext context) + { + return Uni.createFrom().item(QuarkusSecurityIdentity.builder().setPrincipal(new QuarkusPrincipal("67f2814b-f8af-42b2-be9e-8a43cde383ec")).build()); + } } \ No newline at end of file diff --git a/src/main/java/dev/dinauer/maven/Lists.java b/src/main/java/dev/dinauer/maven/Lists.java new file mode 100644 index 0000000..0c9d6f0 --- /dev/null +++ b/src/main/java/dev/dinauer/maven/Lists.java @@ -0,0 +1,15 @@ +package dev.dinauer.maven; + +import java.util.List; + +public class Lists +{ + public static

P getFirst(List

input) + { + if (input == null || input.isEmpty()) + { + return null; + } + return input.getFirst(); + } +} diff --git a/src/main/java/dev/dinauer/maven/app/ArtifactResource.java b/src/main/java/dev/dinauer/maven/app/ArtifactResource.java index a327afa..def2149 100644 --- a/src/main/java/dev/dinauer/maven/app/ArtifactResource.java +++ b/src/main/java/dev/dinauer/maven/app/ArtifactResource.java @@ -25,9 +25,11 @@ public class ArtifactResource @RestClient UserClient userClient; + @Inject + ResponseEnhancementService responseEnhancementService; @GET - public List get() + public EnhancedResponse get() { return find(); } @@ -47,15 +49,9 @@ public class ArtifactResource artifactRepo.deleteById(id); } - private List find() + private EnhancedResponse find() { - List artifactIds = artifactRepo.listAll(); - Map accounts = getAccounts(artifactIds); - for (ArtifactId artifactId : artifactIds) - { - System.out.println("Skip setting user. Needs to be implemented"); - } - return artifactIds; + return responseEnhancementService.enhance(artifactRepo.listAll()); } private Map getAccounts(List artifactIds) diff --git a/src/main/java/dev/dinauer/maven/app/EnhancedResponse.java b/src/main/java/dev/dinauer/maven/app/EnhancedResponse.java new file mode 100644 index 0000000..6eacdb7 --- /dev/null +++ b/src/main/java/dev/dinauer/maven/app/EnhancedResponse.java @@ -0,0 +1,10 @@ +package dev.dinauer.maven.app; + +import dev.dinauer.maven.user.User; + +import java.util.Map; +import java.util.Objects; + +public record EnhancedResponse(Object data, Map users) +{ +} diff --git a/src/main/java/dev/dinauer/maven/app/GroupResource.java b/src/main/java/dev/dinauer/maven/app/GroupResource.java index ed15591..ca338ce 100644 --- a/src/main/java/dev/dinauer/maven/app/GroupResource.java +++ b/src/main/java/dev/dinauer/maven/app/GroupResource.java @@ -6,6 +6,7 @@ import dev.dinauer.maven.event.Resource; import dev.dinauer.maven.event.repo.EventRepo; import dev.dinauer.maven.maven.core.GroupRepo; import dev.dinauer.maven.maven.core.GroupId; +import io.quarkus.security.identity.SecurityIdentity; import jakarta.inject.Inject; import jakarta.transaction.Transactional; import jakarta.ws.rs.DELETE; @@ -21,9 +22,13 @@ public class GroupResource { @Inject GroupRepo groupRepo; + @Inject EventRepo eventRepo; + @Inject + SecurityIdentity securityIdentity; + @GET public List get() { @@ -46,7 +51,7 @@ public class GroupResource if (groupId != null) { groupRepo.delete(groupId); - eventRepo.persist(new Event().setType(EventType.DELETE).setTimestamp(ZonedDateTime.now()).setResource(new Resource().setGroupId(groupId.getGroupId()))); + eventRepo.persist(new Event().setUserId(securityIdentity.getPrincipal().getName()).setType(EventType.DELETE).setTimestamp(ZonedDateTime.now()).setResource(new Resource().setGroupId(groupId.getGroupId()))); } } } diff --git a/src/main/java/dev/dinauer/maven/app/ResponseEnhancementService.java b/src/main/java/dev/dinauer/maven/app/ResponseEnhancementService.java new file mode 100644 index 0000000..a1786e8 --- /dev/null +++ b/src/main/java/dev/dinauer/maven/app/ResponseEnhancementService.java @@ -0,0 +1,22 @@ +package dev.dinauer.maven.app; + +import dev.dinauer.maven.shared.UserReferencing; +import dev.dinauer.maven.user.UserClient; +import jakarta.enterprise.context.ApplicationScoped; +import org.eclipse.microprofile.rest.client.inject.RestClient; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@ApplicationScoped +public class ResponseEnhancementService +{ + @RestClient + UserClient userClient; + + public

EnhancedResponse enhance(Collection

data) + { + return new EnhancedResponse(data, userClient.get(data.stream().map(UserReferencing::getUserIds).flatMap(List::stream).collect(Collectors.toSet()))); + } +} diff --git a/src/main/java/dev/dinauer/maven/event/Event.java b/src/main/java/dev/dinauer/maven/event/Event.java index 2556e1e..e7cce28 100644 --- a/src/main/java/dev/dinauer/maven/event/Event.java +++ b/src/main/java/dev/dinauer/maven/event/Event.java @@ -1,14 +1,18 @@ package dev.dinauer.maven.event; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonManagedReference; +import dev.dinauer.maven.shared.UserReferencing; import dev.dinauer.maven.user.User; import jakarta.persistence.*; import java.time.ZonedDateTime; +import java.util.List; @Entity @Table(name = "event") -public class Event +public class Event implements UserReferencing { @Id @GeneratedValue(strategy = GenerationType.UUID) @@ -24,11 +28,8 @@ public class Event private ZonedDateTime timestamp; - @Column(name = "accountId") - private String accountId; - - @Transient - private User user; + @Column(name = "user_id") + private String userId; public String getId() { @@ -74,25 +75,20 @@ public class Event return this; } - public String getAccountId() + public String getUserId() { - return accountId; + return userId; } - public Event setAccountId(String userId) + public Event setUserId(String userId) { - this.accountId = userId; + this.userId = userId; return this; } - public User getAccount() + @Override + public List getUserIds() { - return user; - } - - public Event setAccount(User user) - { - this.user = user; - return this; + return List.of(userId); } } diff --git a/src/main/java/dev/dinauer/maven/event/EventsResource.java b/src/main/java/dev/dinauer/maven/event/EventsResource.java index 02647df..ab5af8a 100644 --- a/src/main/java/dev/dinauer/maven/event/EventsResource.java +++ b/src/main/java/dev/dinauer/maven/event/EventsResource.java @@ -1,5 +1,7 @@ package dev.dinauer.maven.event; +import dev.dinauer.maven.app.EnhancedResponse; +import dev.dinauer.maven.app.ResponseEnhancementService; import dev.dinauer.maven.user.User; import dev.dinauer.maven.event.repo.EventRepo; import dev.dinauer.maven.user.UserClient; @@ -21,33 +23,12 @@ public class EventsResource @Inject EventRepo eventRepo; - @RestClient - UserClient userClient; - @Inject - SecurityContext context; + ResponseEnhancementService responseEnhancementService; @GET - public List get() + public EnhancedResponse get() { - return find(eventRepo.listAll(Sort.by("timestamp", Sort.Direction.Descending))); - } - - private List find(List events) - { - Principal c = context.getUserPrincipal(); - List ids = new ArrayList<>(); - for (Event event : events) - { - ids.add(event.getAccountId()); - } - - Map accounts = userClient.get(ids); - - for (Event event : events) - { - event.setAccount(accounts.get(event.getAccountId())); - } - return events; + return responseEnhancementService.enhance(eventRepo.listAll(Sort.by("timestamp", Sort.Direction.Descending))); } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/ArtifactId.java b/src/main/java/dev/dinauer/maven/maven/core/ArtifactId.java index 783c4a9..9d67ba2 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/ArtifactId.java +++ b/src/main/java/dev/dinauer/maven/maven/core/ArtifactId.java @@ -1,21 +1,24 @@ package dev.dinauer.maven.maven.core; import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; import dev.dinauer.maven.maven.core.release.ReleaseVersion; import dev.dinauer.maven.maven.core.snapshot.SnapshotVersion; +import dev.dinauer.maven.shared.UserReferencing; import jakarta.persistence.*; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Comparator; +import java.util.LinkedList; import java.util.List; import java.util.stream.Stream; @Entity @Table(name = "artifact_id") -public class ArtifactId +public class ArtifactId implements UserReferencing { @Id @GeneratedValue(strategy = GenerationType.UUID) @@ -109,6 +112,10 @@ public class ArtifactId public ArtifactId setUpdatedAt(ZonedDateTime updatedAt) { this.updatedAt = updatedAt; + if (this.group != null) + { + this.group.setUpdatedAt(updatedAt); + } return this; } @@ -146,7 +153,7 @@ public class ArtifactId public List getReleaseVersions() { - return releaseVersions; + return releaseVersions.stream().sorted(Comparator.comparing(item -> new DefaultArtifactVersion(item.getVersion()))).toList().reversed(); } public ArtifactId setReleaseVersions(List releaseVersions) @@ -154,4 +161,15 @@ public class ArtifactId this.releaseVersions = releaseVersions; return this; } + + @Override + public List getUserIds() + { + List userIds = new LinkedList<>(); + for (ReleaseVersion releaseVersion : releaseVersions) + { + userIds.addAll(releaseVersion.getUserIds()); + } + return userIds; + } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/MavenService.java b/src/main/java/dev/dinauer/maven/maven/core/MavenService.java index d2255cd..ef7c28b 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/MavenService.java +++ b/src/main/java/dev/dinauer/maven/maven/core/MavenService.java @@ -1,5 +1,6 @@ package dev.dinauer.maven.maven.core; +import dev.dinauer.maven.maven.core.artifact.metadata.ArtifactMetadataService; import dev.dinauer.maven.maven.core.context.ArtifactContext; import dev.dinauer.maven.maven.core.context.ReleaseContext; import dev.dinauer.maven.maven.core.context.SnapshotContext; @@ -36,6 +37,8 @@ public class MavenService SnapshotService snapshotService; @Inject SnapshotMetadataService snapshotMetadataService; + @Inject + ArtifactMetadataService artifactMetadataService; public void upload(String path, byte[] body) { @@ -96,7 +99,14 @@ public class MavenService } if (context.getClass() == ArtifactContext.class) { - return Response.status(404).build(); + if (context.extensions().hashExt().isEmpty()) + { + return Response.status(200).type(MediaType.APPLICATION_XML).entity(artifactMetadataService.generate(context)).build(); + } + else + { + return Response.status(200).type(MediaType.TEXT_PLAIN).entity(artifactMetadataService.generateHash(context)).build(); + } } throw new BadRequestException(); } diff --git a/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/ArtifactMetadataService.java b/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/ArtifactMetadataService.java new file mode 100644 index 0000000..18d8cca --- /dev/null +++ b/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/ArtifactMetadataService.java @@ -0,0 +1,88 @@ +package dev.dinauer.maven.maven.core.artifact.metadata; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import dev.dinauer.maven.Lists; +import dev.dinauer.maven.maven.core.ArtifactId; +import dev.dinauer.maven.maven.core.ArtifactRepo; +import dev.dinauer.maven.maven.core.Version; +import dev.dinauer.maven.maven.core.artifact.metadata.model.ArtifactMetadata; +import dev.dinauer.maven.maven.core.artifact.metadata.model.ArtifactVersioning; +import dev.dinauer.maven.maven.core.context.ArtifactContext; +import dev.dinauer.maven.maven.core.context.VersionContext; +import dev.dinauer.maven.maven.core.release.ReleaseVersion; +import dev.dinauer.maven.maven.core.snapshot.SnapshotBundle; +import dev.dinauer.maven.maven.core.snapshot.metadata.model.Snapshot; +import dev.dinauer.maven.maven.core.snapshot.metadata.model.SnapshotMetadata; +import dev.dinauer.maven.maven.core.snapshot.metadata.model.SnapshotVersion; +import dev.dinauer.maven.maven.core.snapshot.metadata.model.SnapshotVersioning; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.InternalServerErrorException; +import jakarta.ws.rs.NotFoundException; +import org.apache.commons.codec.digest.DigestUtils; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +@ApplicationScoped +public class ArtifactMetadataService +{ + private static final XmlMapper XML_MAPPER = new XmlMapper(); + private final ArtifactRepo artifactRepo; + + @Inject + public ArtifactMetadataService(ArtifactRepo artifactRepo) + { + this.artifactRepo = artifactRepo; + } + + public String generate(ArtifactContext artifactContext) + { + try + { + return XML_MAPPER.writeValueAsString(generateMetadata(artifactContext)); + } + catch (JsonProcessingException e) + { + throw new InternalServerErrorException(); + } + } + + private ArtifactMetadata generateMetadata(ArtifactContext artifactContext) + { + ArtifactId artifactId = artifactRepo.findOptionalByArtifactId(artifactContext.groupId(), artifactContext.artifactId()).orElseThrow(NotFoundException::new); + ZonedDateTime lastUpdated = artifactId.getUpdatedAt(); + List versions = artifactId.getVersions(); + Version latest = versions.getFirst(); + String latestRelease = latestRelease(artifactId); + return new ArtifactMetadata(artifactId.getGroupId(), artifactId.getArtifactId(), new ArtifactVersioning(latest.getVersion(), latestRelease, versions.stream().map(Version::getVersion).toList().reversed(), lastUpdated.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")))); + } + + public String generateHash(ArtifactContext artifactContext) + { + switch (artifactContext.extensions().hashExt().orElseThrow()) + { + case MD5 -> + { + return DigestUtils.md5Hex(generate(artifactContext)); + } + case SHA256 -> + { + return DigestUtils.sha256Hex(generate(artifactContext)); + } + } + throw new IllegalArgumentException(); + } + + private String latestRelease(ArtifactId artifactId) + { + ReleaseVersion releaseVersion = Lists.getFirst(artifactId.getReleaseVersions()); + if (releaseVersion != null) + { + return releaseVersion.getVersion(); + } + return null; + } +} diff --git a/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/model/ArtifactMetadata.java b/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/model/ArtifactMetadata.java new file mode 100644 index 0000000..980bc86 --- /dev/null +++ b/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/model/ArtifactMetadata.java @@ -0,0 +1,8 @@ +package dev.dinauer.maven.maven.core.artifact.metadata.model; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +@JacksonXmlRootElement(localName = "metadata") +public record ArtifactMetadata(String groupId, String artifactId, ArtifactVersioning versioning) +{ +} diff --git a/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/model/ArtifactVersioning.java b/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/model/ArtifactVersioning.java new file mode 100644 index 0000000..1cda90a --- /dev/null +++ b/src/main/java/dev/dinauer/maven/maven/core/artifact/metadata/model/ArtifactVersioning.java @@ -0,0 +1,11 @@ +package dev.dinauer.maven.maven.core.artifact.metadata.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +import java.util.List; + +public record ArtifactVersioning(String latest, @JsonInclude(JsonInclude.Include.NON_NULL) String release, @JacksonXmlElementWrapper(localName = "versions") @JacksonXmlProperty(localName = "version") List versions, String lastUpdated) +{ +} \ No newline at end of file diff --git a/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePom.java b/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePom.java index 8f67e68..d3b1ef3 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePom.java +++ b/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePom.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; +import java.time.ZonedDateTime; + @Entity @Table(name = "release_pom") public class ReleasePom @@ -30,6 +32,9 @@ public class ReleasePom @JsonBackReference private ReleaseVersion releaseVersion; + @Column(name = "updated_at") + private ZonedDateTime updatedAt; + public String getId() { return id; @@ -106,4 +111,19 @@ public class ReleasePom this.filename = filename; return this; } + + public ZonedDateTime getUpdatedAt() + { + return updatedAt; + } + + public ReleasePom setUpdatedAt(ZonedDateTime updatedAt) + { + this.updatedAt = updatedAt; + if (this.releaseVersion != null) + { + this.releaseVersion.setUpdatedAt(updatedAt); + } + return this; + } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePomService.java b/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePomService.java index d284f69..a98da28 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePomService.java +++ b/src/main/java/dev/dinauer/maven/maven/core/release/ReleasePomService.java @@ -7,6 +7,7 @@ import dev.dinauer.maven.event.repo.EventRepo; import dev.dinauer.maven.maven.core.context.ReleaseContext; import dev.dinauer.maven.maven.core.context.SnapshotContext; import dev.dinauer.maven.maven.core.model.FileHash; +import io.quarkus.security.identity.SecurityIdentity; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.WebApplicationException; @@ -24,13 +25,17 @@ public class ReleasePomService @Inject ReleaseVersionService releaseVersionService; + @Inject EventRepo eventRepo; + @Inject + SecurityIdentity securityIdentity; + public void store(ReleaseContext releaseContext, byte[] body) { - ReleasePom jar = releasePomRepo.find(releaseContext); - if (jar == null) + ReleasePom pom = releasePomRepo.find(releaseContext); + if (pom == null) { create(releaseContext, body); createEvent(releaseContext); @@ -65,11 +70,12 @@ public class ReleasePomService releasePom.setMd5(DigestUtils.md5Hex(content)); releasePom.setSha1(DigestUtils.sha1Hex(content)); releasePom.setFilename(releaseContext.filename()); + releasePom.setUpdatedAt(ZonedDateTime.now()); releasePomRepo.persist(releasePom); } private void createEvent(ReleaseContext releaseContext) { - eventRepo.persist(new Event().setType(EventType.UPLOAD).setTimestamp(ZonedDateTime.now()).setResource(new Resource().setGroupId(releaseContext.groupId()).setArtifactId(releaseContext.artifactId()).setVersion(releaseContext.version()).setSnapshot(false))); + eventRepo.persist(new Event().setUserId(securityIdentity.getPrincipal().getName()).setType(EventType.UPLOAD).setTimestamp(ZonedDateTime.now()).setResource(new Resource().setGroupId(releaseContext.groupId()).setArtifactId(releaseContext.artifactId()).setVersion(releaseContext.version()).setSnapshot(false))); } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersion.java b/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersion.java index 454351b..f36276d 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersion.java +++ b/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersion.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonManagedReference; import dev.dinauer.maven.maven.core.ArtifactId; import dev.dinauer.maven.maven.core.Version; +import dev.dinauer.maven.shared.UserReferencing; import dev.dinauer.maven.user.User; import jakarta.persistence.*; @@ -14,7 +15,7 @@ import java.util.Optional; @Entity @Table(name = "release_version") -public class ReleaseVersion implements Version +public class ReleaseVersion implements Version, UserReferencing { @Id @GeneratedValue(strategy = GenerationType.UUID) @@ -50,6 +51,9 @@ public class ReleaseVersion implements Version @Column(name = "uploaded_by") private String uploadedBy; + @Column(name = "updated_at") + private ZonedDateTime updatedAt; + @Transient private User uploadUser; @@ -191,6 +195,27 @@ public class ReleaseVersion implements Version return Optional.empty(); } + public ZonedDateTime getUpdatedAt() + { + return updatedAt; + } + + public ReleaseVersion setUpdatedAt(ZonedDateTime updatedAt) + { + this.updatedAt = updatedAt; + if (this.artifact != null) + { + artifact.setUpdatedAt(updatedAt); + } + return this; + } + + @Override + public List getUserIds() + { + return List.of(uploadedBy); + } + @Override public boolean isSnapshot() { diff --git a/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersionService.java b/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersionService.java index 1679249..e488496 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersionService.java +++ b/src/main/java/dev/dinauer/maven/maven/core/release/ReleaseVersionService.java @@ -2,8 +2,10 @@ package dev.dinauer.maven.maven.core.release; import dev.dinauer.maven.maven.core.ArtifactService; import dev.dinauer.maven.maven.core.context.VersionContext; +import io.quarkus.security.identity.SecurityIdentity; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; +import jakarta.ws.rs.core.SecurityContext; @ApplicationScoped public class ReleaseVersionService @@ -14,6 +16,9 @@ public class ReleaseVersionService @Inject ArtifactService artifactService; + @Inject + SecurityIdentity securityIdentity; + public ReleaseVersion findOrCreate(VersionContext versionContext) { ReleaseVersion releaseVersion = releaseVersionRepo.findByGroupIdAndArtifactIdAndVersion(versionContext.groupId(), versionContext.artifactId(), versionContext.version()); @@ -26,6 +31,7 @@ public class ReleaseVersionService ReleaseVersion created = new ReleaseVersion(); created.setArtifact(artifactService.findOrCreate(versionContext.groupId(), versionContext.artifactId())); created.setVersion(versionContext.version()); + created.setUploadedBy(securityIdentity.getPrincipal().getName()); releaseVersionRepo.persist(created); return created; } diff --git a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundle.java b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundle.java index 4178f27..8db89e8 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundle.java +++ b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundle.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; +import java.time.ZonedDateTime; import java.util.List; @Entity @@ -34,6 +35,12 @@ public class SnapshotBundle @JsonManagedReference private SnapshotPom pom; + @Column(name = "updated_at") + private ZonedDateTime updatedAt; + + @Column(name = "uploaded_by") + private String uploadedBy; + public String getId() { return id; @@ -115,4 +122,30 @@ public class SnapshotBundle this.pom = pom; return this; } + + public ZonedDateTime getUpdatedAt() + { + return updatedAt; + } + + public SnapshotBundle setUpdatedAt(ZonedDateTime updatedAt) + { + this.updatedAt = updatedAt; + if (this.snapshotVersion != null) + { + this.snapshotVersion.setUpdatedAt(updatedAt); + } + return this; + } + + public String getUploadedBy() + { + return uploadedBy; + } + + public SnapshotBundle setUploadedBy(String uploadedBy) + { + this.uploadedBy = uploadedBy; + return this; + } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundleService.java b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundleService.java index e5b51cf..59d7b2e 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundleService.java +++ b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotBundleService.java @@ -1,6 +1,7 @@ package dev.dinauer.maven.maven.core.snapshot; import dev.dinauer.maven.maven.core.context.SnapshotContext; +import io.quarkus.security.identity.SecurityIdentity; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.NotFoundException; @@ -14,6 +15,9 @@ public class SnapshotBundleService @Inject SnapshotVersionService snapshotVersionService; + @Inject + SecurityIdentity securityIdentity; + public SnapshotBundle findOrCreate(SnapshotContext snapshotContext) { SnapshotVersion snapshotVersion = snapshotVersionService.findOrCreate(snapshotContext); @@ -29,6 +33,7 @@ public class SnapshotBundleService created.setTime(snapshotContext.time()); created.setBuildNumber(snapshotContext.buildNumber()); created.setSnapshotVersion(snapshotVersion); + created.setUploadedBy(securityIdentity.getPrincipal().getName()); snapshotBundleRepo.persist(created); return created; } diff --git a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJar.java b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJar.java index 650fd37..d97cc86 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJar.java +++ b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJar.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; +import java.time.ZonedDateTime; + @Entity @Table(name = "snapshot_jar") public class SnapshotJar diff --git a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJarService.java b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJarService.java index a606b05..d6c8c6c 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJarService.java +++ b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotJarService.java @@ -8,6 +8,8 @@ import jakarta.ws.rs.WebApplicationException; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.NotImplementedException; +import java.time.ZonedDateTime; + @ApplicationScoped public class SnapshotJarService { diff --git a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotPomService.java b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotPomService.java index 476352c..895ea0e 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotPomService.java +++ b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotPomService.java @@ -6,6 +6,7 @@ import dev.dinauer.maven.event.Resource; import dev.dinauer.maven.event.repo.EventRepo; import dev.dinauer.maven.maven.core.context.ReleaseContext; import dev.dinauer.maven.maven.core.context.SnapshotContext; +import io.quarkus.security.identity.SecurityIdentity; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.WebApplicationException; @@ -27,6 +28,9 @@ public class SnapshotPomService @Inject SnapshotBundleService snapshotBundleService; + @Inject + SecurityIdentity securityIdentity; + public void store(SnapshotContext snapshotContext, byte[] body) { SnapshotBundle snapshotBundle = snapshotBundleService.findOrCreate(snapshotContext); @@ -35,6 +39,7 @@ public class SnapshotPomService { create(snapshotBundle, body); createEvent(snapshotContext); + snapshotBundle.setUpdatedAt(ZonedDateTime.now()); } else { @@ -72,6 +77,6 @@ public class SnapshotPomService private void createEvent(SnapshotContext snapshotContext) { - eventRepo.persist(new Event().setType(EventType.UPLOAD).setTimestamp(ZonedDateTime.now()).setResource(new Resource().setGroupId(snapshotContext.groupId()).setArtifactId(snapshotContext.artifactId()).setVersion(snapshotContext.plainVersion()).setSnapshot(true))); + eventRepo.persist(new Event().setUserId(securityIdentity.getPrincipal().getName()).setType(EventType.UPLOAD).setTimestamp(ZonedDateTime.now()).setResource(new Resource().setGroupId(snapshotContext.groupId()).setArtifactId(snapshotContext.artifactId()).setVersion(snapshotContext.plainVersion()).setSnapshot(true))); } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotVersion.java b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotVersion.java index 8fcdb85..6b77310 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotVersion.java +++ b/src/main/java/dev/dinauer/maven/maven/core/snapshot/SnapshotVersion.java @@ -6,6 +6,7 @@ import dev.dinauer.maven.maven.core.ArtifactId; import dev.dinauer.maven.maven.core.Version; import jakarta.persistence.*; +import java.time.ZonedDateTime; import java.util.List; @Entity @@ -27,6 +28,9 @@ public class SnapshotVersion implements Version @JsonManagedReference private List snapshotBundles; + @Column(name = "updated_at") + private ZonedDateTime updatedAt; + public String getId() { return id; @@ -71,6 +75,21 @@ public class SnapshotVersion implements Version return this; } + public ZonedDateTime getUpdatedAt() + { + return updatedAt; + } + + public SnapshotVersion setUpdatedAt(ZonedDateTime updatedAt) + { + this.updatedAt = updatedAt; + if (this.artifact != null) + { + this.artifact.setUpdatedAt(updatedAt); + } + return this; + } + @Override public boolean isSnapshot() { diff --git a/src/main/java/dev/dinauer/maven/shared/UserReferencing.java b/src/main/java/dev/dinauer/maven/shared/UserReferencing.java new file mode 100644 index 0000000..5fcb79c --- /dev/null +++ b/src/main/java/dev/dinauer/maven/shared/UserReferencing.java @@ -0,0 +1,11 @@ +package dev.dinauer.maven.shared; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.util.List; + +public interface UserReferencing +{ + @JsonIgnore + List getUserIds(); +} \ No newline at end of file diff --git a/src/main/java/dev/dinauer/maven/user/User.java b/src/main/java/dev/dinauer/maven/user/User.java index 7ceeb3a..85b7fee 100644 --- a/src/main/java/dev/dinauer/maven/user/User.java +++ b/src/main/java/dev/dinauer/maven/user/User.java @@ -1,5 +1,12 @@ package dev.dinauer.maven.user; +import com.fasterxml.jackson.annotation.JsonProperty; + public record User(String id, String firstname, String lastname, String email) { -} + @JsonProperty("displayName") + public String displayName() + { + return String.format("%s, %s", firstname, lastname); + } +} \ No newline at end of file diff --git a/src/main/java/dev/dinauer/maven/user/UserClient.java b/src/main/java/dev/dinauer/maven/user/UserClient.java index c252ef3..f7389af 100644 --- a/src/main/java/dev/dinauer/maven/user/UserClient.java +++ b/src/main/java/dev/dinauer/maven/user/UserClient.java @@ -8,6 +8,7 @@ import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import java.util.List; import java.util.Map; +import java.util.Set; @Path("/users") @OidcClientFilter @@ -19,5 +20,5 @@ public interface UserClient @POST @Path("/search") - Map get(List ids); + Map get(Set ids); } diff --git a/src/main/resources/db/migration/V1.0.0__init.sql b/src/main/resources/db/migration/V1.0.0__init.sql index ceaf892..9a1c7b6 100644 --- a/src/main/resources/db/migration/V1.0.0__init.sql +++ b/src/main/resources/db/migration/V1.0.0__init.sql @@ -8,6 +8,8 @@ create table group_id primary key ); +alter table group_id owner to postgres; + create table artifact_id ( created_at timestamp(6) with time zone, @@ -22,10 +24,13 @@ create table artifact_id primary key ); +alter table artifact_id owner to postgres; + create table release_version ( pull_count integer, last_pulled timestamp(6) with time zone, + updated_at timestamp(6) with time zone, artifact_id varchar(255) constraint fk7c5hahrl7ws76sidh9d1434b8 references artifact_id, @@ -38,6 +43,8 @@ create table release_version version varchar(255) ); +alter table release_version owner to postgres; + create table release_jar ( classifier varchar(255), @@ -54,8 +61,11 @@ create table release_jar jar bytea ); +alter table release_jar owner to postgres; + create table release_pom ( + updated_at timestamp(6) with time zone, filename varchar(255), id varchar(255) not null constraint release_pom_pkey @@ -71,21 +81,24 @@ create table release_pom url varchar(255) ); +alter table release_pom owner to postgres; + create table resource ( + is_snapshot boolean, artifact_id varchar(255), group_id varchar(255), - is_snapshot boolean, id varchar(255) not null constraint resource_pkey primary key, version varchar(255) ); +alter table resource owner to postgres; + create table event ( timestamp timestamp(6) with time zone, - accountid varchar(255), id varchar(255) not null constraint event_pkey primary key, @@ -96,11 +109,15 @@ create table event references resource, type varchar(255) constraint event_type_check - check ((type)::text = ANY ((ARRAY['UPLOAD'::character varying, 'DELETE'::character varying])::text[])) - ); + check ((type)::text = ANY ((ARRAY['UPLOAD'::character varying, 'DELETE'::character varying])::text[])), + user_id varchar(255) +); + +alter table event owner to postgres; create table snapshot_version ( + updated_at timestamp(6) with time zone, artifact_id varchar(255) constraint fk64mje366563n82s8hy9bkfr14 references artifact_id, @@ -110,9 +127,12 @@ create table snapshot_version version varchar(255) ); +alter table snapshot_version owner to postgres; + create table snapshot_bundle ( build_number integer, + updated_at timestamp(6) with time zone, date varchar(255), id varchar(255) not null constraint snapshot_bundle_pkey @@ -120,9 +140,12 @@ create table snapshot_bundle snapshot_version_id varchar(255) constraint fk3ve4wtmuywedyrri24dnqrpd9 references snapshot_version, - time varchar(255) + time varchar(255), + uploaded_by varchar(255) ); +alter table snapshot_bundle owner to postgres; + create table snapshot_jar ( classifier varchar(255), @@ -137,6 +160,8 @@ create table snapshot_jar jar bytea ); +alter table snapshot_jar owner to postgres; + create table snapshot_pom ( id varchar(255) not null @@ -152,6 +177,8 @@ create table snapshot_pom references snapshot_bundle ); +alter table snapshot_pom owner to postgres; + create table token ( expires_at date, @@ -162,4 +189,7 @@ create table token name varchar(255), token varchar(255), user_id varchar(255) -); \ No newline at end of file +); + +alter table token owner to postgres; +