Re-update to 3.30.5 #83
@ -20,7 +20,7 @@ jobs:
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '17.0.12'
|
||||
java-version: '21'
|
||||
distribution: 'graalvm'
|
||||
cache: 'maven'
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -50,3 +50,4 @@ nb-configuration.xml
|
||||
/media/
|
||||
/media-ext/
|
||||
/sign.jpg
|
||||
/.gitea/workflows/test.yml
|
||||
|
||||
18
pom.xml
18
pom.xml
@ -11,7 +11,7 @@
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
|
||||
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
|
||||
<quarkus.platform.version>3.16.4</quarkus.platform.version>
|
||||
<quarkus.platform.version>3.30.5</quarkus.platform.version>
|
||||
<skipITs>true</skipITs>
|
||||
<surefire-plugin.version>3.2.3</surefire-plugin.version>
|
||||
</properties>
|
||||
@ -56,19 +56,15 @@
|
||||
<artifactId>quarkus-rest-client-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-mssql-client</artifactId>
|
||||
<version>4.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.quarkiverse.tika</groupId>
|
||||
<artifactId>quarkus-tika</artifactId>
|
||||
<version>2.0.4</version>
|
||||
<groupId>io.quarkiverse.antivirus</groupId>
|
||||
<artifactId>quarkus-antivirus</artifactId>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -96,7 +92,7 @@
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.22</version>
|
||||
<version>1.18.42</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@ -127,7 +123,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlgraphics</groupId>
|
||||
<artifactId>fop</artifactId>
|
||||
<version>2.6</version>
|
||||
<version>2.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
|
||||
@ -64,6 +64,9 @@ public class AffiliationService {
|
||||
@Inject
|
||||
LoggerService ls;
|
||||
|
||||
@Inject
|
||||
VirusScannerService scanner;
|
||||
|
||||
@RestClient
|
||||
StateIdService stateIdService;
|
||||
|
||||
@ -174,15 +177,12 @@ public class AffiliationService {
|
||||
LOGGER.debug("Affiliation Request Created");
|
||||
LOGGER.debug(form.toString());
|
||||
|
||||
// noinspection ResultOfMethodCallIgnored,ReactiveStreamsUnusedPublisher
|
||||
// noinspection ReactiveStreamsUnusedPublisher
|
||||
return pre_save(form, true)
|
||||
.chain(model -> Panache.withTransaction(() -> repositoryRequest.persist(model)))
|
||||
.onItem()
|
||||
.invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getLogo(), media,
|
||||
"aff_request/logo")))
|
||||
.onItem()
|
||||
.invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getStatus(), media,
|
||||
"aff_request/status")))
|
||||
.invoke(m -> Utils.uploadFile(scanner, form.getLogo(), m.getId(), media, "aff_request/logo"))
|
||||
.invoke(m -> Utils.uploadFile(scanner, form.getStatus(), m.getId(), media, "aff_request/status"))
|
||||
.call(model -> reactiveMailer.send(
|
||||
Mail.withText("no-reply@ffsaf.fr",
|
||||
"[NOTIF] FFSAF - Nouvelle demande d'affiliation",
|
||||
@ -245,11 +245,8 @@ public class AffiliationService {
|
||||
})
|
||||
.chain(model -> Panache.withTransaction(() -> repositoryRequest.persist(model)))
|
||||
.onItem()
|
||||
.invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getLogo(), media,
|
||||
"aff_request/logo")))
|
||||
.onItem()
|
||||
.invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getStatus(), media,
|
||||
"aff_request/status")))
|
||||
.invoke(m -> Utils.uploadFile(scanner, form.getLogo(), m.getId(), media, "aff_request/logo"))
|
||||
.invoke(m -> Utils.uploadFile(scanner, form.getStatus(), m.getId(), media, "aff_request/status"))
|
||||
.map(__ -> "Ok");
|
||||
}
|
||||
|
||||
@ -319,13 +316,11 @@ public class AffiliationService {
|
||||
.recoverWithNull()
|
||||
.call(___ -> setMembre(form.new Member(3), club, req.getSaison()))))
|
||||
.onItem()
|
||||
.invoke(model -> Uni.createFrom()
|
||||
.future(Utils.replacePhoto(form.getId(), form.getLogo(), media,
|
||||
"aff_request/logo")))
|
||||
.invoke(model -> Utils.uploadFile(scanner, form.getLogo(), form.getId(), media,
|
||||
"aff_request/logo"))
|
||||
.invoke(model -> Utils.uploadFile(scanner, form.getStatus(), form.getId(), media,
|
||||
"aff_request/status"))
|
||||
.onItem()
|
||||
.invoke(model -> Uni.createFrom()
|
||||
.future(Utils.replacePhoto(form.getId(), form.getStatus(), media,
|
||||
"aff_request/status")))
|
||||
.call(model -> Utils.moveMedia(form.getId(), model.getId(), media, "aff_request/logo",
|
||||
"ppClub"))
|
||||
.call(model -> Utils.moveMedia(form.getId(), model.getId(), media, "aff_request/status",
|
||||
|
||||
@ -467,7 +467,7 @@ public class MembreService {
|
||||
.call(membreModel -> licenceRepository.update("club_id = ?1 where membre = ?2 AND saison = ?3",
|
||||
(membreModel.getClub() == null) ? null : membreModel.getClub().getId(), membreModel,
|
||||
Utils.getSaison()))
|
||||
.call(membreModel -> membre.getPhoto_data().length > 0 ? ls.logAUpdate("Photo",
|
||||
.call(membreModel -> (membre.getPhoto_data() != null && membre.getPhoto_data().size() > 0) ? ls.logAUpdate("Photo",
|
||||
membreModel) : Uni.createFrom().nullItem())
|
||||
.map(__ -> "OK");
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package fr.titionfire.ffsaf.domain.service;
|
||||
|
||||
import io.quarkiverse.antivirus.runtime.Antivirus;
|
||||
import io.quarkiverse.antivirus.runtime.AntivirusScanResult;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@ApplicationScoped
|
||||
public class VirusScannerService {
|
||||
|
||||
@Inject
|
||||
Antivirus antivirus;
|
||||
|
||||
public Uni<List<AntivirusScanResult>> scanFileReactive(String fileName, InputStream inputStream) {
|
||||
System.out.println("Starting reactive virus scan for file: " + fileName);
|
||||
|
||||
// Wrap the blocking antivirus scan in a reactive context
|
||||
// This moves the blocking operation to a worker thread
|
||||
return Uni.createFrom().item(() -> {
|
||||
System.out.println("Scanning file on worker thread: " + fileName);
|
||||
return antivirus.scan(fileName, inputStream);
|
||||
}).runSubscriptionOn(io.smallrye.mutiny.infrastructure.Infrastructure.getDefaultWorkerPool());
|
||||
}
|
||||
}
|
||||
@ -3,10 +3,10 @@ package fr.titionfire.ffsaf.rest;
|
||||
import fr.titionfire.ffsaf.data.model.ClubModel;
|
||||
import fr.titionfire.ffsaf.domain.service.ClubService;
|
||||
import fr.titionfire.ffsaf.domain.service.PDFService;
|
||||
import fr.titionfire.ffsaf.domain.service.VirusScannerService;
|
||||
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
|
||||
import fr.titionfire.ffsaf.rest.data.*;
|
||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||
import fr.titionfire.ffsaf.rest.exception.DInternalError;
|
||||
import fr.titionfire.ffsaf.rest.from.FullClubForm;
|
||||
import fr.titionfire.ffsaf.rest.from.PartClubForm;
|
||||
import fr.titionfire.ffsaf.utils.Contact;
|
||||
@ -47,6 +47,9 @@ public class ClubEndpoints {
|
||||
@Inject
|
||||
SecurityCtx securityCtx;
|
||||
|
||||
@Inject
|
||||
VirusScannerService scannerService;
|
||||
|
||||
@ConfigProperty(name = "upload_dir")
|
||||
String media;
|
||||
|
||||
@ -121,9 +124,8 @@ public class ClubEndpoints {
|
||||
})
|
||||
public Uni<SimpleClub> getById(
|
||||
@Parameter(description = "Identifiant de club") @PathParam("id") long id) {
|
||||
return clubService.getById(id).onItem().invoke(checkPerm).map(SimpleClub::fromModel).invoke(m -> {
|
||||
m.setContactMap(Contact.toSite());
|
||||
});
|
||||
return clubService.getById(id).onItem().invoke(checkPerm).map(SimpleClub::fromModel)
|
||||
.invoke(m -> m.setContactMap(Contact.toSite()));
|
||||
}
|
||||
|
||||
@PUT
|
||||
@ -145,25 +147,9 @@ public class ClubEndpoints {
|
||||
return clubService.update(id, input)
|
||||
.invoke(Unchecked.consumer(out -> {
|
||||
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
|
||||
})).chain(() -> {
|
||||
if (input.getLogo().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getLogo(), media, "ppClub"
|
||||
)).invoke(Unchecked.consumer(out -> {
|
||||
if (!out.equals("OK"))
|
||||
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
|
||||
})); // TODO log
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
}).chain(() -> {
|
||||
if (input.getStatus().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getStatus(), media, "clubStatus"
|
||||
)).invoke(Unchecked.consumer(out -> {
|
||||
if (!out.equals("OK"))
|
||||
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
|
||||
})); // TODO log
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
});
|
||||
}))
|
||||
.chain(() -> Utils.uploadFile(scannerService, input.getLogo(), id, media, "ppClub"))
|
||||
.chain(() -> Utils.uploadFile(scannerService, input.getStatus(), id, media, "clubStatus"));
|
||||
}
|
||||
|
||||
@PUT
|
||||
@ -181,19 +167,9 @@ public class ClubEndpoints {
|
||||
return clubService.add(input)
|
||||
.invoke(Unchecked.consumer(id -> {
|
||||
if (id == null) throw new InternalError("Fail to create club data");
|
||||
})).call(id -> {
|
||||
if (input.getLogo().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getLogo(), media, "ppClub"
|
||||
)); // TODO log
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
}).call(id -> {
|
||||
if (input.getStatus().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getStatus(), media, "clubStatus"
|
||||
)); // TODO log
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
});
|
||||
}))
|
||||
.call(id -> Utils.uploadFile(scannerService, input.getLogo(), id, media, "ppClub"))
|
||||
.call(id -> Utils.uploadFile(scannerService, input.getStatus(), id, media, "clubStatus"));
|
||||
}
|
||||
|
||||
@DELETE
|
||||
|
||||
@ -2,6 +2,7 @@ package fr.titionfire.ffsaf.rest;
|
||||
|
||||
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||
import fr.titionfire.ffsaf.domain.service.MembreService;
|
||||
import fr.titionfire.ffsaf.domain.service.VirusScannerService;
|
||||
import fr.titionfire.ffsaf.rest.data.SimpleMembre;
|
||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||
import fr.titionfire.ffsaf.rest.exception.DInternalError;
|
||||
@ -21,6 +22,7 @@ import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@ -29,10 +31,14 @@ import java.util.function.Consumer;
|
||||
@Path("api/member")
|
||||
@RolesAllowed({"federation_admin"})
|
||||
public class MembreAdminEndpoints {
|
||||
private static final Logger LOGGER = Logger.getLogger(MembreAdminEndpoints.class);
|
||||
|
||||
@Inject
|
||||
MembreService membreService;
|
||||
|
||||
@Inject
|
||||
VirusScannerService scannerService;
|
||||
|
||||
@ConfigProperty(name = "upload_dir")
|
||||
String media;
|
||||
|
||||
@ -97,16 +103,8 @@ public class MembreAdminEndpoints {
|
||||
.invoke(Unchecked.consumer(out -> {
|
||||
if (!out.equals("OK"))
|
||||
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
|
||||
})).chain(() -> {
|
||||
if (input.getPhoto_data().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||
)).invoke(Unchecked.consumer(out -> {
|
||||
if (!out.equals("OK"))
|
||||
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
|
||||
}));
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
});
|
||||
}))
|
||||
.call(__ -> Utils.uploadFile(scannerService, input.getPhoto_data(), id, media, "ppMembre"));
|
||||
}
|
||||
|
||||
@POST
|
||||
@ -123,13 +121,8 @@ public class MembreAdminEndpoints {
|
||||
return membreService.add(input)
|
||||
.invoke(Unchecked.consumer(id -> {
|
||||
if (id == null) throw new InternalError("Fail to creat member data");
|
||||
})).call(id -> {
|
||||
if (input.getPhoto_data().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||
));
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
});
|
||||
}))
|
||||
.call(id -> Utils.uploadFile(scannerService, input.getPhoto_data(), id, media, "ppMembre"));
|
||||
}
|
||||
|
||||
@DELETE
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package fr.titionfire.ffsaf.rest;
|
||||
|
||||
import fr.titionfire.ffsaf.domain.service.MembreService;
|
||||
import fr.titionfire.ffsaf.domain.service.VirusScannerService;
|
||||
import fr.titionfire.ffsaf.rest.data.SimpleMembre;
|
||||
import fr.titionfire.ffsaf.rest.data.SimpleMembreInOutData;
|
||||
import fr.titionfire.ffsaf.rest.exception.DInternalError;
|
||||
import fr.titionfire.ffsaf.rest.from.FullMemberForm;
|
||||
import fr.titionfire.ffsaf.utils.PageResult;
|
||||
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
||||
@ -37,6 +37,9 @@ public class MembreClubEndpoints {
|
||||
@Inject
|
||||
SecurityCtx securityCtx;
|
||||
|
||||
@Inject
|
||||
VirusScannerService scannerService;
|
||||
|
||||
@GET
|
||||
@Path("/find/club")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -59,7 +62,8 @@ public class MembreClubEndpoints {
|
||||
limit = 50;
|
||||
if (page == null || page < 1)
|
||||
page = 1;
|
||||
return membreService.search(limit, page - 1, search, licenceRequest, payment, order, categorie, archive, securityCtx.getSubject());
|
||||
return membreService.search(limit, page - 1, search, licenceRequest, payment, order, categorie, archive,
|
||||
securityCtx.getSubject());
|
||||
}
|
||||
|
||||
@GET
|
||||
@ -107,16 +111,7 @@ public class MembreClubEndpoints {
|
||||
return membreService.update(id, input, securityCtx)
|
||||
.invoke(Unchecked.consumer(out -> {
|
||||
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
|
||||
})).chain(() -> {
|
||||
if (input.getPhoto_data().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||
)).invoke(Unchecked.consumer(out -> {
|
||||
if (!out.equals("OK"))
|
||||
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
|
||||
}));
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
});
|
||||
})).chain(() -> Utils.uploadFile(scannerService, input.getPhoto_data(), id, media, "ppMembre"));
|
||||
}
|
||||
|
||||
@POST
|
||||
@ -134,13 +129,7 @@ public class MembreClubEndpoints {
|
||||
return membreService.add(input, securityCtx.getSubject())
|
||||
.invoke(Unchecked.consumer(id -> {
|
||||
if (id == null) throw new InternalError("Fail to creat member data");
|
||||
})).call(id -> {
|
||||
if (input.getPhoto_data().length > 0)
|
||||
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||
));
|
||||
else
|
||||
return Uni.createFrom().nullItem();
|
||||
});
|
||||
})).call(id -> Utils.uploadFile(scannerService, input.getPhoto_data(), id, media, "ppMembre"));
|
||||
}
|
||||
|
||||
@DELETE
|
||||
|
||||
@ -9,6 +9,7 @@ import lombok.ToString;
|
||||
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
import org.jboss.resteasy.reactive.PartType;
|
||||
import org.jboss.resteasy.reactive.multipart.FileUpload;
|
||||
|
||||
@Getter
|
||||
@ToString(exclude = {"status", "logo"})
|
||||
@ -17,85 +18,85 @@ public class AffiliationRequestForm {
|
||||
@FormParam("id")
|
||||
private Long id = null;
|
||||
|
||||
@Schema(description = "Le nom de l'association.", example = "Association sportive", required = true)
|
||||
@Schema(description = "Le nom de l'association.", examples = "Association sportive", required = true)
|
||||
@FormParam("name")
|
||||
private String name = null;
|
||||
|
||||
@Schema(description = "Le numéro SIRET/RNA de l'association.", example = "12345678901234", required = true)
|
||||
@Schema(description = "Le numéro SIRET/RNA de l'association.", examples = "12345678901234", required = true)
|
||||
@FormParam("state_id")
|
||||
private String state_id = null;
|
||||
|
||||
@Schema(description = "L'adresse de l'association.", example = "1 rue de l'exemple, 75000 Paris", required = true)
|
||||
@Schema(description = "L'adresse de l'association.", examples = "1 rue de l'exemple, 75000 Paris", required = true)
|
||||
@FormParam("adresse")
|
||||
private String adresse = null;
|
||||
|
||||
@Schema(description = "Email de contact de l'association", example = "test@test.fr")
|
||||
@Schema(description = "Email de contact de l'association", examples = "test@test.fr")
|
||||
@FormParam("contact")
|
||||
private String contact = null;
|
||||
|
||||
@Schema(description = "La saison de l'affiliation.", example = "2025", required = true)
|
||||
@Schema(description = "La saison de l'affiliation.", examples = "2025", required = true)
|
||||
@FormParam("saison")
|
||||
private int saison = -1;
|
||||
|
||||
@Schema(description = "Le statut de l'association.", type = SchemaType.ARRAY, implementation = byte.class)
|
||||
@Schema(description = "Le statut de l'association.", type = SchemaType.ARRAY)
|
||||
@FormParam("status")
|
||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
private byte[] status = new byte[0];
|
||||
private FileUpload status = null;
|
||||
|
||||
@Schema(description = "Le logo de l'association.", type = SchemaType.ARRAY, implementation = byte.class)
|
||||
@Schema(description = "Le logo de l'association.", type = SchemaType.ARRAY)
|
||||
@FormParam("logo")
|
||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
private byte[] logo = new byte[0];
|
||||
private FileUpload logo = null;
|
||||
|
||||
@Schema(description = "Le nom du premier membre de l'association.", example = "Doe", required = true)
|
||||
@Schema(description = "Le nom du premier membre de l'association.", examples = "Doe", required = true)
|
||||
@FormParam("m1_nom")
|
||||
private String m1_lname = null;
|
||||
|
||||
@Schema(description = "Le prénom du premier membre de l'association.", example = "John", required = true)
|
||||
@Schema(description = "Le prénom du premier membre de l'association.", examples = "John", required = true)
|
||||
@FormParam("m1_prenom")
|
||||
private String m1_fname = null;
|
||||
|
||||
@Schema(description = "L'adresse e-mail du premier membre de l'association.", example = "john.doe@test.com", required = true)
|
||||
@Schema(description = "L'adresse e-mail du premier membre de l'association.", examples = "john.doe@test.com", required = true)
|
||||
@FormParam("m1_mail")
|
||||
private String m1_email = null;
|
||||
|
||||
@Schema(description = "Le numéro de licence du premier membre de l'association. (null si non licencié)", example = "12345")
|
||||
@Schema(description = "Le numéro de licence du premier membre de l'association. (null si non licencié)", examples = "12345")
|
||||
@FormParam("m1_licence")
|
||||
private String m1_lincence = null;
|
||||
|
||||
@Schema(description = "Le rôle du premier membre de l'association. (doit être PRESIDENT)", example = "PRESIDENT", required = true)
|
||||
@Schema(description = "Le rôle du premier membre de l'association. (doit être PRESIDENT)", examples = "PRESIDENT", required = true)
|
||||
@FormParam("m1_role")
|
||||
private RoleAsso m1_role = null;
|
||||
|
||||
@Schema(description = "Le nom du deuxième membre de l'association.", example = "Xavier", required = true)
|
||||
@Schema(description = "Le nom du deuxième membre de l'association.", examples = "Xavier", required = true)
|
||||
@FormParam("m2_nom")
|
||||
private String m2_lname = null;
|
||||
|
||||
@Schema(description = "Le prénom du deuxième membre de l'association.", example = "Login", required = true)
|
||||
@Schema(description = "Le prénom du deuxième membre de l'association.", examples = "Login", required = true)
|
||||
@FormParam("m2_prenom")
|
||||
private String m2_fname = null;
|
||||
|
||||
@Schema(description = "L'adresse e-mail du deuxième membre de l'association.", example = "xavier.login@test.com", required = true)
|
||||
@Schema(description = "L'adresse e-mail du deuxième membre de l'association.", examples = "xavier.login@test.com", required = true)
|
||||
@FormParam("m2_mail")
|
||||
private String m2_email = null;
|
||||
|
||||
@Schema(description = "Le numéro de licence du deuxième membre de l'association. (null si non licencié)", example = "04242")
|
||||
@Schema(description = "Le numéro de licence du deuxième membre de l'association. (null si non licencié)", examples = "04242")
|
||||
@FormParam("m2_licence")
|
||||
private String m2_lincence = null;
|
||||
|
||||
@Schema(description = "Le rôle du deuxième membre de l'association.", example = "SECRETAIRE", required = true)
|
||||
@Schema(description = "Le rôle du deuxième membre de l'association.", examples = "SECRETAIRE", required = true)
|
||||
@FormParam("m2_role")
|
||||
private RoleAsso m2_role = null;
|
||||
|
||||
@Schema(description = "Le nom du troisième membre de l'association.", example = "Doe2", required = true)
|
||||
@Schema(description = "Le nom du troisième membre de l'association.", examples = "Doe2", required = true)
|
||||
@FormParam("m3_nom")
|
||||
private String m3_lname = null;
|
||||
|
||||
@Schema(description = "Le prénom du troisième membre de l'association.", example = "John2", required = true)
|
||||
@Schema(description = "Le prénom du troisième membre de l'association.", examples = "John2", required = true)
|
||||
@FormParam("m3_prenom")
|
||||
private String m3_fname = null;
|
||||
|
||||
@Schema(description = "L'adresse e-mail du troisième membre de l'association.", example = "john.doe22@test.com", required = true)
|
||||
@Schema(description = "L'adresse e-mail du troisième membre de l'association.", examples = "john.doe22@test.com", required = true)
|
||||
@FormParam("m3_mail")
|
||||
private String m3_email = null;
|
||||
|
||||
@ -103,7 +104,7 @@ public class AffiliationRequestForm {
|
||||
@FormParam("m3_licence")
|
||||
private String m3_lincence = null;
|
||||
|
||||
@Schema(description = "Le rôle du troisième membre de l'association.", example = "MEMBREBUREAU", required = true)
|
||||
@Schema(description = "Le rôle du troisième membre de l'association.", examples = "MEMBREBUREAU", required = true)
|
||||
@FormParam("m3_role")
|
||||
private RoleAsso m3_role = null;
|
||||
|
||||
|
||||
@ -6,123 +6,124 @@ import jakarta.ws.rs.core.MediaType;
|
||||
import lombok.Getter;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
import org.jboss.resteasy.reactive.PartType;
|
||||
import org.jboss.resteasy.reactive.multipart.FileUpload;
|
||||
|
||||
@Getter
|
||||
public class AffiliationRequestSaveForm {
|
||||
@Schema(description = "L'identifiant de l'affiliation.", example = "1", required = true)
|
||||
@Schema(description = "L'identifiant de l'affiliation.", examples = "1", required = true)
|
||||
@FormParam("id")
|
||||
private Long id = null;
|
||||
|
||||
@Schema(description = "Le nom de l'association.", example = "Association sportive", required = true)
|
||||
@Schema(description = "Le nom de l'association.", examples = "Association sportive", required = true)
|
||||
@FormParam("name")
|
||||
private String name = null;
|
||||
|
||||
@Schema(description = "Le numéro SIRET ou RNA de l'association.", example = "12345678901234", required = true)
|
||||
@Schema(description = "Le numéro SIRET ou RNA de l'association.", examples = "12345678901234", required = true)
|
||||
@FormParam("state_id")
|
||||
private String state_id = null;
|
||||
|
||||
@Schema(description = "L'adresse de l'association.", example = "1 rue de l'exemple, 75000 Paris", required = true)
|
||||
@Schema(description = "L'adresse de l'association.", examples = "1 rue de l'exemple, 75000 Paris", required = true)
|
||||
@FormParam("address")
|
||||
private String address = null;
|
||||
|
||||
@Schema(description = "Email de contact de l'association", example = "test@test.fr")
|
||||
@Schema(description = "Email de contact de l'association", examples = "test@test.fr")
|
||||
@FormParam("contact")
|
||||
private String contact = null;
|
||||
|
||||
@Schema(description = "Le statut de l'association.")
|
||||
@FormParam("status")
|
||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
private byte[] status = new byte[0];
|
||||
private FileUpload status = null;
|
||||
|
||||
@Schema(description = "Le logo de l'association.")
|
||||
@FormParam("logo")
|
||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
private byte[] logo = new byte[0];
|
||||
private FileUpload logo = null;
|
||||
|
||||
@Schema(description = "Mode utiliser pour la sauvegarde du membre 1 (0 = licence mode, 2 = nom, prénom)", example = "0", required = true)
|
||||
@Schema(description = "Mode utiliser pour la sauvegarde du membre 1 (0 = licence mode, 2 = nom, prénom)", examples = "0", required = true)
|
||||
@FormParam("m1_mode")
|
||||
private Integer m1_mode = null;
|
||||
|
||||
@Schema(description = "Le rôle du premier membre de l'association.", example = "PRÉSIDENT", required = true)
|
||||
@Schema(description = "Le rôle du premier membre de l'association.", examples = "PRÉSIDENT", required = true)
|
||||
@FormParam("m1_role")
|
||||
private RoleAsso m1_role = null;
|
||||
|
||||
@Schema(description = "Le numéro de licence du premier membre de l'association. (null si non licencié)", example = "1234567", required = true)
|
||||
@Schema(description = "Le numéro de licence du premier membre de l'association. (null si non licencié)", examples = "1234567", required = true)
|
||||
@FormParam("m1_licence")
|
||||
private String m1_lincence = null;
|
||||
|
||||
@Schema(description = "Le nom du premier membre de l'association.", example = "Dupont", required = true)
|
||||
@Schema(description = "Le nom du premier membre de l'association.", examples = "Dupont", required = true)
|
||||
@FormParam("m1_lname")
|
||||
private String m1_lname = null;
|
||||
|
||||
@Schema(description = "Le prénom du premier membre de l'association.", example = "Jean", required = true)
|
||||
@Schema(description = "Le prénom du premier membre de l'association.", examples = "Jean", required = true)
|
||||
@FormParam("m1_fname")
|
||||
private String m1_fname = null;
|
||||
|
||||
@Schema(description = "L'adresse e-mail du premier membre de l'association.", example = "jean.dupont@example.com", required = true)
|
||||
@Schema(description = "L'adresse e-mail du premier membre de l'association.", examples = "jean.dupont@examples.com", required = true)
|
||||
@FormParam("m1_email")
|
||||
private String m1_email = null;
|
||||
|
||||
@Schema(name = "keep_email",
|
||||
description = "Conserver l'email de la base de donner (1 = conserve, 0 = replacer par 'm1_email')", example = "1", required = true)
|
||||
description = "Conserver l'email de la base de donner (1 = conserve, 0 = replacer par 'm1_email')", examples = "1", required = true)
|
||||
@FormParam("m1_email_mode")
|
||||
private Integer m1_email_mode = null;
|
||||
|
||||
@Schema(description = "Mode utiliser pour la sauvegarde du membre 2 (0 = licence mode, 2 = nom, prénom)", example = "0", required = true)
|
||||
@Schema(description = "Mode utiliser pour la sauvegarde du membre 2 (0 = licence mode, 2 = nom, prénom)", examples = "0", required = true)
|
||||
@FormParam("m2_mode")
|
||||
private Integer m2_mode = null;
|
||||
|
||||
@Schema(description = "Le rôle du deuxième membre de l'association.", example = "TRÉSORIER", required = true)
|
||||
@Schema(description = "Le rôle du deuxième membre de l'association.", examples = "TRÉSORIER", required = true)
|
||||
@FormParam("m2_role")
|
||||
private RoleAsso m2_role = null;
|
||||
|
||||
@Schema(description = "Le numéro de licence du deuxième membre de l'association. (null si non licencié)", example = "2345678", required = true)
|
||||
@Schema(description = "Le numéro de licence du deuxième membre de l'association. (null si non licencié)", examples = "2345678", required = true)
|
||||
@FormParam("m2_licence")
|
||||
private String m2_lincence = null;
|
||||
|
||||
@Schema(description = "Le nom du deuxième membre de l'association.", example = "Durand", required = true)
|
||||
@Schema(description = "Le nom du deuxième membre de l'association.", examples = "Durand", required = true)
|
||||
@FormParam("m2_lname")
|
||||
private String m2_lname = null;
|
||||
|
||||
@Schema(description = "Le prénom du deuxième membre de l'association.", example = "Paul", required = true)
|
||||
@Schema(description = "Le prénom du deuxième membre de l'association.", examples = "Paul", required = true)
|
||||
@FormParam("m2_fname")
|
||||
private String m2_fname = null;
|
||||
|
||||
@Schema(description = "L'adresse e-mail du deuxième membre de l'association.", example = "paul.durand@example.com", required = true)
|
||||
@Schema(description = "L'adresse e-mail du deuxième membre de l'association.", examples = "paul.durand@examples.com", required = true)
|
||||
@FormParam("m2_email")
|
||||
private String m2_email = null;
|
||||
|
||||
@Schema(name = "keep_email",
|
||||
description = "Conserver l'email de la base de donner (1 = conserve, 0 = replacer par 'm2_email')", example = "1", required = true)
|
||||
description = "Conserver l'email de la base de donner (1 = conserve, 0 = replacer par 'm2_email')", examples = "1", required = true)
|
||||
@FormParam("m2_email_mode")
|
||||
private Integer m2_email_mode = null;
|
||||
|
||||
@Schema(description = "Mode utiliser pour la sauvegarde du membre 3 (0 = licence mode, 2 = nom, prénom)", example = "0", required = true)
|
||||
@Schema(description = "Mode utiliser pour la sauvegarde du membre 3 (0 = licence mode, 2 = nom, prénom)", examples = "0", required = true)
|
||||
@FormParam("m3_mode")
|
||||
private Integer m3_mode = null;
|
||||
|
||||
@Schema(description = "Le rôle du troisième membre de l'association.", example = "SECRÉTAIRE", required = true)
|
||||
@Schema(description = "Le rôle du troisième membre de l'association.", examples = "SECRÉTAIRE", required = true)
|
||||
@FormParam("m3_role")
|
||||
private RoleAsso m3_role = null;
|
||||
|
||||
@Schema(description = "Le numéro de licence du troisième membre de l'association. (null si non licencié)", example = "3456789", required = true)
|
||||
@Schema(description = "Le numéro de licence du troisième membre de l'association. (null si non licencié)", examples = "3456789", required = true)
|
||||
@FormParam("m3_licence")
|
||||
private String m3_lincence = null;
|
||||
|
||||
@Schema(description = "Le nom du troisième membre de l'association.", example = "Martin", required = true)
|
||||
@Schema(description = "Le nom du troisième membre de l'association.", examples = "Martin", required = true)
|
||||
@FormParam("m3_lname")
|
||||
private String m3_lname = null;
|
||||
|
||||
@Schema(description = "Le prénom du troisième membre de l'association.", example = "Pierre", required = true)
|
||||
@Schema(description = "Le prénom du troisième membre de l'association.", examples = "Pierre", required = true)
|
||||
@FormParam("m3_fname")
|
||||
private String m3_fname = null;
|
||||
|
||||
@Schema(description = "L'adresse e-mail du troisième membre de l'association.", example = "pierre.martin@example.com", required = true)
|
||||
@Schema(description = "L'adresse e-mail du troisième membre de l'association.", examples = "pierre.martin@examples.com", required = true)
|
||||
@FormParam("m3_email")
|
||||
private String m3_email = null;
|
||||
|
||||
@Schema(name = "keep_email",
|
||||
description = "Conserver l'email de la base de donner (1 = conserve, 0 = replacer par 'm3_email')", example = "1", required = true)
|
||||
description = "Conserver l'email de la base de donner (1 = conserve, 0 = replacer par 'm3_email')", examples = "1", required = true)
|
||||
@FormParam("m3_email_mode")
|
||||
private Integer m3_email_mode = null;
|
||||
|
||||
@ -174,8 +175,6 @@ public class AffiliationRequestSaveForm {
|
||||
", state_id=" + state_id +
|
||||
", address='" + address + '\'' +
|
||||
", contact='" + contact + '\'' +
|
||||
", status_len=" + status.length +
|
||||
", logo_len=" + logo.length +
|
||||
", m1_mode=" + m1_mode +
|
||||
", m1_role=" + m1_role +
|
||||
", m1_lincence='" + m1_lincence + '\'' +
|
||||
|
||||
@ -7,57 +7,58 @@ import lombok.ToString;
|
||||
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
import org.jboss.resteasy.reactive.PartType;
|
||||
import org.jboss.resteasy.reactive.multipart.FileUpload;
|
||||
|
||||
@ToString
|
||||
@Getter
|
||||
public class FullClubForm {
|
||||
@FormParam("id")
|
||||
@Schema(description = "Identifiant du club", example = "1", required = true)
|
||||
@Schema(description = "Identifiant du club", examples = "1", required = true)
|
||||
private String id = null;
|
||||
|
||||
@FormParam("name")
|
||||
@Schema(description = "Nom du club", example = "Association sportive", required = true)
|
||||
@Schema(description = "Nom du club", examples = "Association sportive", required = true)
|
||||
private String name = null;
|
||||
|
||||
@FormParam("country")
|
||||
@Schema(description = "Pays du club", example = "FR", required = true)
|
||||
@Schema(description = "Pays du club", examples = "FR", required = true)
|
||||
private String country = null;
|
||||
|
||||
@FormParam("contact")
|
||||
@Schema(description = "Les contacts du club", example = "{\"SITE\": \"www.test.com\", \"COURRIEL\": \"test@test.com\"}", required = true)
|
||||
@Schema(description = "Les contacts du club", examples = "{\"SITE\": \"www.test.com\", \"COURRIEL\": \"test@test.com\"}", required = true)
|
||||
private String contact = null;
|
||||
|
||||
@FormParam("training_location")
|
||||
@Schema(description = "Liste des lieux d'entraînement", example = "[{\"text\":\"addr 1\",\"lng\":2.24654,\"lat\":52.4868658},{\"text\":\"addr 2\",\"lng\":2.88654,\"lat\":52.7865456}]", required = true)
|
||||
@Schema(description = "Liste des lieux d'entraînement", examples = "[{\"text\":\"addr 1\",\"lng\":2.24654,\"lat\":52.4868658},{\"text\":\"addr 2\",\"lng\":2.88654,\"lat\":52.7865456}]", required = true)
|
||||
private String training_location = null;
|
||||
|
||||
@FormParam("training_day_time")
|
||||
@Schema(description = "Liste des jours et horaires d'entraînement (jours 0-6, 0=>lundi) (temps en minute depuis 00:00, 122=>2h02)", example = "[{\"day\":0,\"time_start\":164,\"time_end\":240},{\"day\":3,\"time_start\":124,\"time_end\":250}]", required = true)
|
||||
@Schema(description = "Liste des jours et horaires d'entraînement (jours 0-6, 0=>lundi) (temps en minute depuis 00:00, 122=>2h02)", examples = "[{\"day\":0,\"time_start\":164,\"time_end\":240},{\"day\":3,\"time_start\":124,\"time_end\":250}]", required = true)
|
||||
private String training_day_time = null;
|
||||
|
||||
@FormParam("contact_intern")
|
||||
@Schema(description = "Contact interne du club", example = "john.doe@test.com")
|
||||
@Schema(description = "Contact interne du club", examples = "john.doe@test.com")
|
||||
private String contact_intern = null;
|
||||
|
||||
@FormParam("address")
|
||||
@Schema(description = "Adresse postale du club", example = "1 rue de l'exemple, 75000 Paris", required = true)
|
||||
@Schema(description = "Adresse postale du club", examples = "1 rue de l'exemple, 75000 Paris", required = true)
|
||||
private String address = null;
|
||||
|
||||
@FormParam("state_id")
|
||||
@Schema(description = "Numéro SIRET ou RNA du club", example = "12345678901234", required = true)
|
||||
@Schema(description = "Numéro SIRET ou RNA du club", examples = "12345678901234", required = true)
|
||||
private String state_id = null;
|
||||
|
||||
@FormParam("international")
|
||||
@Schema(description = "Club international", example = "false", required = true)
|
||||
@Schema(description = "Club international", examples = "false", required = true)
|
||||
private boolean international = false;
|
||||
|
||||
@FormParam("status")
|
||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@Schema(description = "Le statut de l'association.", type = SchemaType.ARRAY, implementation = byte.class)
|
||||
private byte[] status = new byte[0];
|
||||
@Schema(description = "Le statut de l'association.", type = SchemaType.ARRAY)
|
||||
private FileUpload status = null;
|
||||
|
||||
@FormParam("logo")
|
||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@Schema(description = "Le logo de l'association.", type = SchemaType.ARRAY, implementation = byte.class)
|
||||
private byte[] logo = new byte[0];
|
||||
@Schema(description = "Le logo de l'association.", type = SchemaType.ARRAY)
|
||||
private FileUpload logo = null;
|
||||
}
|
||||
|
||||
@ -8,32 +8,33 @@ import jakarta.ws.rs.core.MediaType;
|
||||
import lombok.Getter;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
import org.jboss.resteasy.reactive.PartType;
|
||||
import org.jboss.resteasy.reactive.multipart.FileUpload;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Getter
|
||||
public class FullMemberForm {
|
||||
@Schema(description = "L'identifiant du membre.", example = "1")
|
||||
@Schema(description = "L'identifiant du membre.", examples = "1")
|
||||
@FormParam("id")
|
||||
private String id = null;
|
||||
|
||||
@Schema(description = "Le nom du membre.", example = "Dupont")
|
||||
@Schema(description = "Le nom du membre.", examples = "Dupont")
|
||||
@FormParam("lname")
|
||||
private String lname = null;
|
||||
|
||||
@Schema(description = "Le prénom du membre.", example = "Jean")
|
||||
@Schema(description = "Le prénom du membre.", examples = "Jean")
|
||||
@FormParam("fname")
|
||||
private String fname = null;
|
||||
|
||||
@Schema(description = "L'identifiant du club du membre.", example = "1")
|
||||
@Schema(description = "L'identifiant du club du membre.", examples = "1")
|
||||
@FormParam("club")
|
||||
private Long club = null;
|
||||
|
||||
@Schema(description = "Le genre du membre.", example = "H")
|
||||
@Schema(description = "Le genre du membre.", examples = "H")
|
||||
@FormParam("genre")
|
||||
private Genre genre;
|
||||
|
||||
@Schema(description = "Le pays du membre.", example = "FR")
|
||||
@Schema(description = "Le pays du membre.", examples = "FR")
|
||||
@FormParam("country")
|
||||
private String country;
|
||||
|
||||
@ -41,22 +42,22 @@ public class FullMemberForm {
|
||||
@FormParam("birth_date")
|
||||
private Date birth_date = null;
|
||||
|
||||
@Schema(description = "L'adresse e-mail du membre.", example = "jean.dupont@example.com")
|
||||
@Schema(description = "L'adresse e-mail du membre.", examples = "jean.dupont@example.com")
|
||||
@FormParam("email")
|
||||
private String email;
|
||||
|
||||
@Schema(description = "Le rôle du membre dans l'association.", example = "MEMBRE")
|
||||
@Schema(description = "Le rôle du membre dans l'association.", examples = "MEMBRE")
|
||||
@FormParam("role")
|
||||
private RoleAsso role;
|
||||
|
||||
@Schema(description = "Le grade d'arbitrage du membre.", example = "ASSESSEUR")
|
||||
@Schema(description = "Le grade d'arbitrage du membre.", examples = "ASSESSEUR")
|
||||
@FormParam("grade_arbitrage")
|
||||
private GradeArbitrage grade_arbitrage = GradeArbitrage.NA;
|
||||
|
||||
@Schema(description = "La photo du membre.")
|
||||
@FormParam("photo_data")
|
||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
private byte[] photo_data = new byte[0];
|
||||
private FileUpload photo_data = null;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -70,7 +71,6 @@ public class FullMemberForm {
|
||||
", email='" + email + '\'' +
|
||||
", role=" + role +
|
||||
", grade_arbitrage=" + grade_arbitrage +
|
||||
", url_photo=" + photo_data.length +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,13 +2,19 @@ package fr.titionfire.ffsaf.utils;
|
||||
|
||||
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
||||
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||
import fr.titionfire.ffsaf.domain.service.VirusScannerService;
|
||||
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
||||
import fr.titionfire.ffsaf.rest.exception.DInternalError;
|
||||
import fr.titionfire.ffsaf.rest.exception.DetailException;
|
||||
import io.quarkiverse.antivirus.runtime.AntivirusScanResult;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import io.smallrye.mutiny.unchecked.Unchecked;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jodd.net.MimeTypes;
|
||||
import org.apache.tika.Tika;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.resteasy.reactive.multipart.FileUpload;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
@ -183,44 +189,72 @@ public class Utils {
|
||||
});
|
||||
}
|
||||
|
||||
public static Future<String> replacePhoto(long id, byte[] input, String media, String dir) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (input == null || input.length == 0)
|
||||
return "OK";
|
||||
public static Uni<String> uploadFile(VirusScannerService ss, FileUpload file, long id, String media, String dir) {
|
||||
if (file == null || file.size() == 0)
|
||||
return Uni.createFrom().item("Ok");
|
||||
|
||||
try (InputStream is = new BufferedInputStream(new ByteArrayInputStream(input))) {
|
||||
String mimeType;
|
||||
try {
|
||||
Tika tika = new Tika();
|
||||
mimeType = tika.detect(is);// Magic.getMagicMatch(input, false).getMimeType();
|
||||
} catch (IOException e) {
|
||||
mimeType = URLConnection.guessContentTypeFromStream(is);
|
||||
}
|
||||
String[] detectedExtensions = MimeTypes.findExtensionsByMimeTypes(mimeType, false);
|
||||
if (detectedExtensions.length == 0)
|
||||
throw new IOException("Fail to detect file extension for MIME type " + mimeType);
|
||||
|
||||
File dirFile = new File(media, dir);
|
||||
if (!dirFile.exists())
|
||||
if (!dirFile.mkdirs())
|
||||
throw new IOException("Fail to create directory " + dir);
|
||||
|
||||
FilenameFilter filter = (directory, filename) -> filename.startsWith(id + ".");
|
||||
File[] files = dirFile.listFiles(filter);
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
LOGGER.infof("Received file upload request for: %s (size: %d bytes)", file.fileName(), file.size());
|
||||
return Uni.createFrom().<InputStream>item(() -> {
|
||||
try {
|
||||
// Read the entire file into memory for virus scanning
|
||||
// ByteArrayInputStream fully supports mark/reset operations required by ClamAV
|
||||
// This ensures we can scan the file content before any filesystem storage
|
||||
InputStream fileStream = java.nio.file.Files.newInputStream(file.uploadedFile());
|
||||
byte[] fileBytes = fileStream.readAllBytes();
|
||||
fileStream.close(); // Close the file stream immediately
|
||||
return new ByteArrayInputStream(fileBytes);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to read uploaded file: " + e.getMessage(), e);
|
||||
}
|
||||
}).runSubscriptionOn(io.smallrye.mutiny.infrastructure.Infrastructure.getDefaultWorkerPool()).onItem()
|
||||
.transformToUni(inputStream -> {
|
||||
// Perform virus scanning reactively using the input stream
|
||||
return ss.scanFileReactive(file.fileName(), inputStream).onItem().invoke(() -> {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Warning: Failed to close input stream: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
})
|
||||
.onItem().transformToUni(scanResults -> Uni.createFrom().item(Unchecked.supplier(() -> {
|
||||
// Check if any scanner found a threat
|
||||
for (AntivirusScanResult result : scanResults) {
|
||||
if (result.getStatus() != Response.Status.OK.getStatusCode()) {
|
||||
LOGGER.warnf("THREAT DETECTED in %s: %s", file.fileName(), result.getMessage());
|
||||
throw new DetailException(Response.Status.fromStatusCode(result.getStatus()),
|
||||
"THREAT_DETECTED on File " + file.fileName() + " is infected: " + result.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String extension = "." + detectedExtensions[0];
|
||||
Files.write(new File(dirFile, id + extension).toPath(), input);
|
||||
return "OK";
|
||||
} catch (IOException e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
});
|
||||
// File is clean - now we can safely process it
|
||||
LOGGER.infof("File is clean: %s (size=%d) (contentType=%s)", file.fileName(), file.size(),
|
||||
file.contentType());
|
||||
|
||||
String[] detectedExtensions = MimeTypes.findExtensionsByMimeTypes(file.contentType(), false);
|
||||
if (detectedExtensions.length == 0)
|
||||
throw new DBadRequestException(
|
||||
"Fail to detect file extension for MIME type " + file.contentType());
|
||||
|
||||
File dirFile = new File(media, dir);
|
||||
if (!dirFile.exists())
|
||||
if (!dirFile.mkdirs())
|
||||
throw new DInternalError("Fail to create directory " + dir);
|
||||
|
||||
FilenameFilter filter = (directory, filename) -> filename.startsWith(id + ".");
|
||||
File[] files = dirFile.listFiles(filter);
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
|
||||
File f = file.filePath().toFile();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
f.renameTo(new File(dirFile, id + "." + detectedExtensions[0]));
|
||||
return "ok";
|
||||
})));
|
||||
}
|
||||
|
||||
public static Uni<Response> getMediaFile(long id, String media, String dirname,
|
||||
@ -368,8 +402,8 @@ public class Utils {
|
||||
return result.toString().trim();
|
||||
}
|
||||
|
||||
public static String getFullName(Object ...models) {
|
||||
for (Object model : models){
|
||||
public static String getFullName(Object... models) {
|
||||
for (Object model : models) {
|
||||
if (model == null)
|
||||
continue;
|
||||
if (model instanceof MembreModel membreModel)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user