rajah 11 месяцев назад
Родитель
Сommit
9a2fcbd74a

BIN
.gradle/8.11.1/checksums/checksums.lock


BIN
.gradle/8.11.1/executionHistory/executionHistory.bin


BIN
.gradle/8.11.1/executionHistory/executionHistory.lock


BIN
.gradle/8.11.1/fileHashes/fileHashes.bin


BIN
.gradle/8.11.1/fileHashes/fileHashes.lock


BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock


BIN
.gradle/file-system.probe


+ 1 - 0
build.gradle

@@ -28,6 +28,7 @@ dependencies {
   implementation 'net.coobird:thumbnailator:0.4.20'
 	implementation 'org.json:json:20250107'
 	implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
+	implementation 'org.apache.httpcomponents.client5:httpclient5:5.4.3'
 	
 	runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
   runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'

+ 12 - 0
src/main/java/fr/triplea/demovote/dao/WebcamRepository.java

@@ -0,0 +1,12 @@
+package fr.triplea.demovote.dao;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import fr.triplea.demovote.model.Webcam;
+
+public interface WebcamRepository  extends JpaRepository<Webcam, Integer> 
+{
+
+  Webcam find(Integer id);
+
+}

+ 83 - 0
src/main/java/fr/triplea/demovote/model/Webcam.java

@@ -0,0 +1,83 @@
+package fr.triplea.demovote.model;
+
+
+import jakarta.persistence.Id;
+import jakarta.persistence.Lob;
+import jakarta.persistence.Table;
+import jakarta.persistence.Transient;
+
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Objects;
+
+import org.hibernate.annotations.JdbcTypeCode;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+
+@Entity(name = "vote.webcams")
+@Table(name = "webcams")
+public class Webcam 
+{
+
+  @Id
+  @Column(name = "id", nullable = false)
+  private Integer id;
+
+  @Column(name = "flag_updated")
+  private Boolean updated = true;
+
+  @Column
+  private Long crc32;
+
+  @Lob @JdbcTypeCode(Types.BINARY)
+  @Column(name="vue")
+  private byte[] vue;
+
+  public void setId(Integer id) { this.id = id; }
+  public Integer getId() { return id; }
+
+
+  public void setUpdated(Boolean updated) { this.updated = updated; }
+  public Boolean isUpdated() { return updated; }
+
+  public void setCrc32(Long crc32) { this.crc32 = crc32; }
+  public Long getCrc32() { return crc32; }
+
+  public void setVue(byte[] vue) { this.vue = vue.clone(); }
+  public byte[] getVue() { return vue; }
+  @Transient
+  public String getVueSRC() { if (this.vue == null) { return ""; } return "data:image/png;base64," + Base64.getEncoder().encodeToString(this.vue); }
+  
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 31;
+    int result = 1;
+    
+    result = prime * result + Arrays.hashCode(vue);
+    result = prime * result + Objects.hash(crc32, id, updated);
+    
+    return result;
+  }
+  
+  @Override
+  public boolean equals(Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+    
+    final Webcam w = (Webcam) obj;
+    
+    if (getId() == null) { if (w.getId() == null) { return false; } } else if (!getId().equals(w.getId())) { return false; }
+    if (getCrc32() == null) { if (w.getCrc32() == null) { return false; } } else if (!getCrc32().equals(w.getCrc32())) { return false; }
+    
+    return true;
+  }
+  
+  @Override
+  public String toString() { return "Webcam [id=" + id + ", updated=" + updated + ", crc32=" + crc32 + "]"; }
+
+}

+ 2 - 0
src/main/java/fr/triplea/demovote/security/ServerConfig.java

@@ -9,10 +9,12 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 import fr.triplea.demovote.security.xss.XssFilter;
 
 @Configuration
+@EnableScheduling
 public class ServerConfig 
 {
 

+ 136 - 0
src/main/java/fr/triplea/demovote/web/client/WebcamsCache.java

@@ -0,0 +1,136 @@
+package fr.triplea.demovote.web.client;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.concurrent.TimeUnit;
+import java.util.zip.CRC32;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.config.TlsConfig;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
+import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.ssl.TLS;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.util.Timeout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import fr.triplea.demovote.dao.VariableRepository;
+import fr.triplea.demovote.dao.WebcamRepository;
+import fr.triplea.demovote.model.Webcam;
+
+public class WebcamsCache 
+{
+
+  private static final Logger LOG = LoggerFactory.getLogger(WebcamsCache.class);
+
+  @Autowired
+  private VariableRepository variableRepository;
+
+  @Autowired
+  private WebcamRepository webcamRepository;
+
+  private int id = 0;
+  
+  @Scheduled(fixedDelay = 30, timeUnit = TimeUnit.SECONDS)
+  public void recuperer() 
+  {
+    if (!(variableRepository.findByTypeAndCode("Caméras", "RECUPERATION_ACTIVE")).equalsIgnoreCase("TRUE")) { return; }
+
+    SSLContext sslContext = null;
+    try 
+    {
+      sslContext = SSLContexts.custom()
+                    .loadTrustMaterial((chain, authType) -> { final X509Certificate cert = chain[0]; return "CN=www.triplea.fr".equalsIgnoreCase(cert.getSubjectX500Principal().getName()); })
+                    .build();
+    } 
+    catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { LOG.error(e.toString()); sslContext = null; }
+        
+    if (sslContext == null) { return; } 
+    
+    TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext);
+   
+    HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
+                                       .setTlsSocketStrategy(tlsStrategy)
+                                       .setDefaultTlsConfig(TlsConfig.custom().setHandshakeTimeout(Timeout.ofSeconds(30)).setSupportedProtocols(TLS.V_1_3).build())
+                                       .build();  
+    
+    if (cm == null) { return; }
+    
+    CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(cm).build();
+    
+    if (httpclient == null) { return; }
+    
+    boolean termine = false;
+    id = 1;
+    String url = null;
+
+    while (termine == false)
+    {
+      url = variableRepository.findByTypeAndCode("Caméras", "RECUPERATION_IMAGE_" + id);
+      
+      if (url == null) { termine = true; }
+      else
+      if (url.equalsIgnoreCase("NONE") || !url.startsWith("https://")) { termine = true; }
+      else
+      {
+        HttpGet httpget = new HttpGet(url);
+        
+        HttpClientContext clientContext = HttpClientContext.create();
+        
+        try 
+        {
+          httpclient.execute(httpget, clientContext, response ->  { if (response.getCode() == 200){ inclureVue(EntityUtils.toByteArray(response.getEntity())); } return null; });
+        } 
+        catch (IOException e) { LOG.error(e.toString()); }
+        
+        id++;
+      }
+    }
+  }
+  
+  private void inclureVue(byte[] b)
+  {
+    Webcam w = webcamRepository.find(id);
+    
+    CRC32 crc = new CRC32();
+    crc.update(b);
+    long c32 = crc.getValue();
+
+    if (w == null) 
+    {
+      w = new Webcam();
+      w.setId(id);
+      w.setUpdated(true);
+      w.setCrc32(c32);
+      w.setVue(b);
+      
+      webcamRepository.save(w);
+    }
+    else 
+    {
+      if (w.getCrc32() != c32)
+      {
+        w.setUpdated(true);
+        w.setCrc32(c32);
+        w.setVue(b);
+
+        webcamRepository.save(w);
+      }
+    }
+  }
+  
+}