uhm ... everything

This commit is contained in:
Hiajen Hiajen 2023-06-10 18:08:49 +02:00
parent c6e9c08a36
commit 35d0d3ca8d
28 changed files with 1216 additions and 1 deletions

View file

@ -1,6 +1,6 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.6'
id 'org.springframework.boot' version '3.1.0'
id 'io.spring.dependency-management' version '1.1.0'
}
@ -16,9 +16,14 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.session:spring-session-core'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'org.springframework.session:spring-session-core'
implementation 'org.springframework.session:spring-session-jdbc'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation("com.github.ua-parser:uap-java:1.5.4")
}
tasks.named('test') {

View file

@ -0,0 +1,30 @@
package de.unileipzig.datenschutz.paper10.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
@Configuration
@EnableJdbcHttpSession
public class Config extends AbstractHttpSessionApplicationInitializer {
@Bean
public EmbeddedDatabase dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}

View file

@ -1,7 +1,17 @@
package de.unileipzig.datenschutz.paper10.demo;
import de.unileipzig.datenschutz.paper10.demo.dto.ScreenSizeData;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
@SpringBootApplication
public class FingerprinitngDemoApplication {

View file

@ -0,0 +1,64 @@
package de.unileipzig.datenschutz.paper10.demo;
import de.unileipzig.datenschutz.paper10.demo.data.FontsFingerprint;
import de.unileipzig.datenschutz.paper10.demo.data.ScreenSizeFinerPrint;
import de.unileipzig.datenschutz.paper10.demo.data.UserSession;
import de.unileipzig.datenschutz.paper10.demo.data.UserSessionRepo;
import de.unileipzig.datenschutz.paper10.demo.dto.FontList;
import de.unileipzig.datenschutz.paper10.demo.dto.FontListDto;
import de.unileipzig.datenschutz.paper10.demo.dto.ScreenSizeData;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
public class UserBackController {
@Autowired
UserSessionRepo userSessionRepo;
@PostMapping("/screensize")
public void receiveScreenSizeData(@RequestBody ScreenSizeData screenSizeData,
final HttpSession session) {
Optional<UserSession> userSession = userSessionRepo.findBySessionID(session.getId());
if (userSession.isEmpty()){
UserSession newSession = new UserSession(session.getId());
userSession = Optional.of(userSessionRepo.save(newSession));
}
if (userSession.get().getScreenSizeFinerPrint() == null){
ScreenSizeFinerPrint screenSizeFinerPrint = new ScreenSizeFinerPrint(screenSizeData.getScreenSize().getWidth(), screenSizeData.getScreenSize().getHeight());
userSession.get().setScreenSizeFinerPrint(screenSizeFinerPrint);
userSessionRepo.save(userSession.get());
}
}
@PostMapping("/fonts")
public void receiveFontsData(@RequestBody Object object,
final HttpSession session){
FontList fontList = FontListDto.parseToFontList(object);
Optional<UserSession> userSession = userSessionRepo.findBySessionID(session.getId());
if (userSession.isEmpty()){
UserSession newSession = new UserSession(session.getId());
userSession = Optional.of(userSessionRepo.save(newSession));
}
if (userSession.get().getFontsFingerprint() == null){
FontsFingerprint fontsFingerprint = new FontsFingerprint(fontList.getInstalledFonts());
userSession.get().setFontsFingerprint(fontsFingerprint);
userSessionRepo.save(userSession.get());
}
}
}

View file

@ -0,0 +1,159 @@
package de.unileipzig.datenschutz.paper10.demo;
import de.unileipzig.datenschutz.paper10.demo.data.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import ua_parser.Parser;
import ua_parser.Client;
import java.util.*;
import java.util.stream.Collectors;
@Controller
public class UserFrontController {
private static final Parser uaParser = new Parser();
@Autowired
UserSessionRepo userSessionRepo;
@Autowired
ScreenSizeFinerPrintRepo screenSizeFinerPrintRepo;
@Autowired
FontsFingerprintRepo fontsFingerprintRepo;
@Autowired
FontsDataRepo fontsDataRepo;
@Autowired
HeaderFingerprintRepo headerFingerprintRepo;
@GetMapping("/")
public String index(final HttpServletRequest request,
final HttpSession session,
final Model model){
Optional<UserSession> userSession = userSessionRepo.findBySessionID(session.getId());
if (userSession.isEmpty()){
UserSession newSession = new UserSession(session.getId());
userSession = Optional.of(userSessionRepo.save(newSession));
}
if (userSession.get().getHeaderFingerprint() == null){
userSession.get().setHeaderFingerprint(parseHeader(request));
userSessionRepo.save(userSession.get());
}
addModelData(model, userSession.get());
return "main";
}
private static HeaderFingerprint parseHeader(final HttpServletRequest request){
Client c = uaParser.parse(request.getHeader("user-agent"));
return new HeaderFingerprint(
c.os.family,
c.os.major,
c.os.minor,
c.device.family,
c.userAgent.family,
c.userAgent.major,
c.userAgent.minor,
Arrays.stream(request.getHeader("accept").split("[,;]")).collect(Collectors.toSet()),
Arrays.stream(request.getHeader("accept-encoding").split(", ")).collect(Collectors.toSet()),
Arrays.stream(request.getHeader("accept-language").split("[,;]")).collect(Collectors.toSet())
);
}
private void addModelData(final Model model,
UserSession userSession){
model.addAttribute("session_id", userSession.getSessionID());
if (userSession.getScreenSizeFinerPrint() != null){
model.addAttribute("show_screen_size", true);
model.addAttribute("screenSizeFinerPrint_width", userSession.getScreenSizeFinerPrint().getWidth());
model.addAttribute("screenSizeFinerPrint_width_count", screenSizeFinerPrintRepo.findAllByWidthEquals(userSession.getScreenSizeFinerPrint().getWidth()).size()/2-1);
model.addAttribute("screenSizeFinerPrint_height", userSession.getScreenSizeFinerPrint().getHeight());
model.addAttribute("screenSizeFinerPrint_height_count", screenSizeFinerPrintRepo.findAllByHeightEquals(userSession.getScreenSizeFinerPrint().getHeight()).size()/2-1);
}
if (userSession.getFontsFingerprint() != null) {
model.addAttribute("show_fonts", true);
model.addAttribute("fontsFingerprint_installedFonts", new FontsModel().generateFontsModelSet(userSession.getFontsFingerprint().getInstalledFonts()));
}
if (userSession.getHeaderFingerprint() != null) {
model.addAttribute("show_header", true);
HeaderFingerprint headerFingerprint = userSession.getHeaderFingerprint();
model.addAttribute("headerFingerprint_os_type", headerFingerprint.getOsType());
model.addAttribute("headerFingerprint_os_type_count", headerFingerprintRepo.findByOsTypeIs(headerFingerprint.getOsType()).size()-1);
model.addAttribute("headerFingerprint_os_version", headerFingerprint.getOsVersion());
model.addAttribute("headerFingerprint_os_version_count", headerFingerprintRepo.findByOsTypeIsAndOsVersionIs(headerFingerprint.getOsType(), headerFingerprint.getOsVersion()).size()-1);
model.addAttribute("headerFingerprint_os_sub_version", headerFingerprint.getOsSubVersion());
model.addAttribute("headerFingerprint_os_sub_version_count", headerFingerprintRepo.findByOsTypeIsAndOsVersionIsAndOsSubVersionIs(headerFingerprint.getOsType(), headerFingerprint.getOsVersion(), headerFingerprint.getOsSubVersion()).size()-1);
model.addAttribute("headerFingerprint_device", headerFingerprint.getDevice());
model.addAttribute("headerFingerprint_device_count", headerFingerprintRepo.findByDeviceIs(headerFingerprint.getDevice()).size()-1);
model.addAttribute("headerFingerprint_useragent_family", headerFingerprint.getUseragentFamily());
model.addAttribute("headerFingerprint_useragent_family_count", headerFingerprintRepo.findByUseragentFamilyIs(headerFingerprint.getUseragentFamily()).size()-1);
model.addAttribute("headerFingerprint_useragent_family_version", headerFingerprint.getUseragentVerison());
model.addAttribute("headerFingerprint_useragent_family_version_count", headerFingerprintRepo.findByUseragentFamilyIsAndUseragentVerisonIs(headerFingerprint.getUseragentFamily(), headerFingerprint.getUseragentVerison()).size()-1);
model.addAttribute("headerFingerprint_useragent_family_sub_version", headerFingerprint.getUseragentSubVersion());
model.addAttribute("headerFingerprint_useragent_family_sub_version_count", headerFingerprintRepo.findByUseragentFamilyIsAndUseragentVerisonIsAndUseragentSubVersionIs(headerFingerprint.getUseragentFamily(), headerFingerprint.getUseragentVerison(), headerFingerprint.getUseragentSubVersion()).size()-1);
model.addAttribute("headerFingerprint_accepts", headerFingerprint.getAccepts().toString());
//model.addAttribute("headerFingerprint_accepts_count", filterAcceptsEquals(headerFingerprint.getAccepts(), headerFingerprintRepo.findAllByAcceptsIn(headerFingerprint.getAccepts())));
model.addAttribute("headerFingerprint_encoding", headerFingerprint.getEncoding().toString());
//model.addAttribute("headerFingerprint_encoding_count", filterAcceptsEquals(headerFingerprint.getEncoding(), headerFingerprintRepo.findAllByEncodingIn(headerFingerprint.getEncoding())));
model.addAttribute("headerFingerprint_languages", headerFingerprint.getLanguages().toString());
//model.addAttribute("headerFingerprint_languages_count", filterAcceptsEquals(headerFingerprint.getLanguages(), headerFingerprintRepo.findAllByLanguagesIs(headerFingerprint.getLanguages())));
}
}
public class FontsModel {
private final String name;
private final int count;
public FontsModel(){
name = null;
count = 0;
}
public FontsModel(String name, int count){
this.name = name;
this.count = count;
}
public ArrayList<FontsModel> generateFontsModelSet(Set<FontsData> usableFonts){
FontsData[] ordered = usableFonts.toArray(FontsData[]::new);
Arrays.sort(ordered, Comparator.comparing(FontsData::getFont));
ArrayList<FontsModel> ret = new ArrayList<>();
for (FontsData font : ordered)
ret.add(new FontsModel(
font.getFont(),
font.getPartOf().size()-1
)
);
return ret;
}
public String getName() {
return name;
}
public int getCount() {
return count;
}
}
}

View file

@ -0,0 +1,8 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import org.springframework.data.repository.CrudRepository;
public interface FingerprintRepo extends CrudRepository<ScreenSizeFinerPrint, Long> {
}

View file

@ -0,0 +1,42 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import java.util.Objects;
import java.util.Set;
@Entity
public class FontsData {
@Id
String font;
@ManyToMany(mappedBy = "installedFonts")
private Set<FontsFingerprint> partOf;
FontsData(){
}
public FontsData(String font) {
this.font = font;
}
public String getFont() {
return font;
}
public void setFont(String font) {
this.font = font;
}
public Set<FontsFingerprint> getPartOf() {
return partOf;
}
public void setPartOf(Set<FontsFingerprint> partOf) {
this.partOf = partOf;
}
}

View file

@ -0,0 +1,6 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import org.springframework.data.repository.CrudRepository;
public interface FontsDataRepo extends CrudRepository<FontsData, String> {
}

View file

@ -0,0 +1,33 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import jakarta.persistence.*;
import java.util.Objects;
import java.util.Set;
@Entity
public class FontsFingerprint {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name="fonts_font",
joinColumns = { @JoinColumn(name="fonts_id")},
inverseJoinColumns = { @JoinColumn(name="font_id")}
)
private Set<FontsData> installedFonts;
FontsFingerprint(){
}
public FontsFingerprint(Set<FontsData> installedFonts) {
this.installedFonts = installedFonts;
}
public Set<FontsData> getInstalledFonts() {
return installedFonts;
}
}

View file

@ -0,0 +1,8 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import org.springframework.data.repository.CrudRepository;
import java.util.Set;
public interface FontsFingerprintRepo extends CrudRepository<FontsFingerprint, Long> {
}

View file

@ -0,0 +1,86 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.util.Objects;
import java.util.Set;
@Entity
public class HeaderFingerprint {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String osType;
private String osVersion;
private String osSubVersion;
private String device;
private String useragentFamily;
private String useragentVerison;
private String useragentSubVersion;
private Set<String> accepts;
private Set<String> encoding;
private Set<String> languages;
HeaderFingerprint(){
}
public HeaderFingerprint(String osType, String osVersion, String osSubVersion, String device, String useragentFamily, String useragentVerison, String useragentSubVersion, Set<String> accepts, Set<String> encoding, Set<String> languages) {
this.osType = osType;
this.osVersion = osVersion;
this.osSubVersion = osSubVersion;
this.device = device;
this.useragentFamily = useragentFamily;
this.useragentVerison = useragentVerison;
this.useragentSubVersion = useragentSubVersion;
this.accepts = accepts;
this.encoding = encoding;
this.languages = languages;
}
public String getOsType() {
return osType;
}
public String getOsVersion() {
return osVersion;
}
public String getOsSubVersion() {
return osSubVersion;
}
public String getDevice() {
return device;
}
public String getUseragentFamily() {
return useragentFamily;
}
public String getUseragentVerison() {
return useragentVerison;
}
public String getUseragentSubVersion() {
return useragentSubVersion;
}
public Set<String> getAccepts() {
return accepts;
}
public Set<String> getEncoding() {
return encoding;
}
public Set<String> getLanguages() {
return languages;
}
}

View file

@ -0,0 +1,16 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import org.springframework.data.repository.CrudRepository;
import java.util.Set;
public interface HeaderFingerprintRepo extends CrudRepository<HeaderFingerprint, Long> {
Set<HeaderFingerprint> findByOsTypeIs(String value);
Set<HeaderFingerprint> findByOsTypeIsAndOsVersionIs(String value, String value2);
Set<HeaderFingerprint> findByOsTypeIsAndOsVersionIsAndOsSubVersionIs(String value, String value2, String value3);
Set<HeaderFingerprint> findByDeviceIs(String value);
Set<HeaderFingerprint> findByUseragentFamilyIs(String value);
Set<HeaderFingerprint> findByUseragentFamilyIsAndUseragentVerisonIs(String value, String value2);
Set<HeaderFingerprint> findByUseragentFamilyIsAndUseragentVerisonIsAndUseragentSubVersionIs(String value, String value2, String value3);
}

View file

@ -0,0 +1,44 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.util.Objects;
@Entity
public class ScreenSizeFinerPrint {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private int width;
private int height;
ScreenSizeFinerPrint(){
}
public ScreenSizeFinerPrint(int screenX, int screenY){
this.width = screenX;
this.height = screenY;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}

View file

@ -0,0 +1,10 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import org.springframework.data.repository.CrudRepository;
import java.util.Set;
public interface ScreenSizeFinerPrintRepo extends CrudRepository<ScreenSizeFinerPrint, Long> {
Set<ScreenSizeFinerPrint> findAllByWidthEquals(int width);
Set<ScreenSizeFinerPrint> findAllByHeightEquals(int height);
}

View file

@ -0,0 +1,67 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import jakarta.persistence.*;
@Entity
public class UserSession {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String sessionID;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "screenSize_id", referencedColumnName = "id")
private ScreenSizeFinerPrint screenSizeFinerPrint;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "fonts_id", referencedColumnName = "id")
private FontsFingerprint fontsFingerprint;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "header_id", referencedColumnName = "id")
private HeaderFingerprint headerFingerprint;
UserSession(){
}
public UserSession(String sessionID){
this.sessionID = sessionID;
}
public String getSessionID() {
return sessionID;
}
public void setSessionID(String sessionID) {
this.sessionID = sessionID;
}
public ScreenSizeFinerPrint getScreenSizeFinerPrint() {
return screenSizeFinerPrint;
}
public void setScreenSizeFinerPrint(ScreenSizeFinerPrint screenSizeFinerPrint) {
this.screenSizeFinerPrint = screenSizeFinerPrint;
}
public FontsFingerprint getFontsFingerprint() {
return fontsFingerprint;
}
public void setFontsFingerprint(FontsFingerprint fontsFingerprint) {
this.fontsFingerprint = fontsFingerprint;
}
public HeaderFingerprint getHeaderFingerprint() {
return headerFingerprint;
}
public void setHeaderFingerprint(HeaderFingerprint headerFingerprint) {
this.headerFingerprint = headerFingerprint;
}
}

View file

@ -0,0 +1,10 @@
package de.unileipzig.datenschutz.paper10.demo.data;
import org.springframework.data.repository.CrudRepository;
import java.util.Optional;
import java.util.Set;
public interface UserSessionRepo extends CrudRepository<UserSession, Long> {
Optional<UserSession> findBySessionID(String sessionID);
}

View file

@ -0,0 +1,34 @@
package de.unileipzig.datenschutz.paper10.demo.dto;
import de.unileipzig.datenschutz.paper10.demo.data.FontsData;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class FontList {
private List<FontStatus> fonts = new ArrayList<FontStatus>();
public List<FontStatus> getFonts() {
return fonts;
}
public void setFonts(List<FontStatus> fonts) {
this.fonts = fonts;
}
public FontStatus getFontStatus(int pos){
return fonts.get(pos);
}
public void addFontStatus(FontStatus fontStatus){
fonts.add(fontStatus);
}
public Set<FontsData> getInstalledFonts(){
return fonts.stream().filter(FontStatus::isActive).map(fontStatus -> new FontsData(fontStatus.getFontName())).collect(Collectors.toSet());
}
}

View file

@ -0,0 +1,37 @@
package de.unileipzig.datenschutz.paper10.demo.dto;
import java.util.ArrayList;
import java.util.List;
public class FontListDto {
ArrayList<ArrayList<String>> fonts;
public ArrayList<ArrayList<String>> getFonts() {
return fonts;
}
public void setFonts(ArrayList<ArrayList<String>> fonts) {
this.fonts = fonts;
}
public static FontList parseToFontList(Object object){
FontList fontList = new FontList();
ArrayList e1 = (ArrayList) object;
for (Object object2 : e1){
ArrayList e2 = (ArrayList) object2;
fontList.addFontStatus(new FontStatus(
(String) e2.get(0),
(Integer) e2.get(1),
(Integer) e2.get(2),
(Boolean) e2.get(3)
));
}
return fontList;
}
}

View file

@ -0,0 +1,49 @@
package de.unileipzig.datenschutz.paper10.demo.dto;
public class FontStatus {
private String fontName;
private int width;
private int height;
private boolean isActive;
public FontStatus(){
}
public FontStatus(String fontName, int width, int height, boolean isActive) {
this.fontName = fontName;
this.width = width;
this.height = height;
this.isActive = isActive;
}
public String getFontName() {
return fontName;
}
public void setFontName(String fontName) {
this.fontName = fontName;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
}

View file

@ -0,0 +1,42 @@
package de.unileipzig.datenschutz.paper10.demo.dto;
import java.util.Objects;
public class ScreenSize {
private int width;
private int height;
public ScreenSize(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ScreenSize that = (ScreenSize) o;
return width == that.width && height == that.height;
}
@Override
public int hashCode() {
return Objects.hash(width, height);
}
}

View file

@ -0,0 +1,27 @@
package de.unileipzig.datenschutz.paper10.demo.dto;
import java.util.Objects;
public class ScreenSizeData {
private ScreenSize screenSize;
public ScreenSize getScreenSize() {
return screenSize;
}
public void setScreenSize(ScreenSize screenSize) {
this.screenSize = screenSize;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ScreenSizeData that = (ScreenSizeData) o;
return Objects.equals(screenSize, that.screenSize);
}
@Override
public int hashCode() {
return Objects.hash(screenSize);
}
}

View file

@ -1 +1,9 @@
spring.thymeleaf.cache=false
spring.session.store-type=jdbc
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p>Get your greeting <a href="/">here</a></p>
</body>
</html>

View file

@ -0,0 +1,150 @@
// Form https://gist.github.com/tingletech/1582068
var Detector = function(){
var h = document.getElementsByTagName("BODY")[0];
var d = document.createElement("DIV");
var s = document.createElement("SPAN");
d.appendChild(s);
d.style.fontFamily = "serif"; //font for the parent element DIV.
s.style.fontFamily = "serif"; //have to use serif coz in FF3.0, it doesn't fall back to font of parent element.
s.style.fontSize = "72px"; //we test using 72px font size, we may use any size. I guess larger the better.
s.innerHTML = "mmmmmmmmmml"; //we use m or w because these two characters take up the maximum width. And we use a L so that the same matching fonts can get separated
h.appendChild(d);
var defaultWidth = s.offsetWidth; //now we have the defaultWidth
var defaultHeight = s.offsetHeight; //and the defaultHeight, we compare other fonts with these.
h.removeChild(d);
/* test
* params:
* font - name of the font you wish to detect
* return:
* f[0] - Input font name.
* f[1] - Computed width.
* f[2] - Computed height.
* f[3] - Detected? (true/false).
*/
function debug(font) {
h.appendChild(d);
var f = [];
f[0] = s.style.fontFamily = font; // Name of the font
f[1] = s.offsetWidth; // Width
f[2] = s.offsetHeight; // Height
h.removeChild(d);
font = font.toLowerCase();
if (font == "serif") {
f[3] = true; // to set arial and sans-serif true
} else {
f[3] = (f[1] != defaultWidth || f[2] != defaultHeight); // Detected?
}
return f;
}
function test(font){
f = debug(font);
return f[3];
}
this.detailedTest = debug;
this.test = test;
}
var fonts = [];
/**
* other stuff
*/
function init() {
fonts.push("cursive");
fonts.push("Helvetica");
fonts.push("monospace");
fonts.push("serif");
fonts.push("sans-serif");
fonts.push("fantasy");
fonts.push("default");
fonts.push("Arial");
fonts.push("Arial Black");
fonts.push("Arial Narrow");
fonts.push("Arial Rounded MT Bold");
fonts.push("Bookman Old Style");
fonts.push("Bradley Hand ITC");
fonts.push("Century");
fonts.push("Century Gothic");
fonts.push("Gotham");
fonts.push("Comic Sans MS");
fonts.push("Courier");
fonts.push("Courier New");
fonts.push("Georgia");
fonts.push("Roboto");
fonts.push("Lato");
fonts.push("Montserrat");
fonts.push("Gentium");
fonts.push("Source Sans Pro");
fonts.push("Bookman");
fonts.push("Brush Script");
fonts.push("PT Sans");
fonts.push("Raleway");
fonts.push("Didot");
fonts.push("Franklin Gothic");
fonts.push("Open Sans");
fonts.push("Univers");
fonts.push("Copperplate");
fonts.push("Impact");
fonts.push("Futura");
fonts.push("Optima");
fonts.push("Rockwell");
fonts.push("Gill Sans");
fonts.push("Zapfino");
fonts.push("Myriad");
fonts.push("King");
fonts.push("Trajan");
fonts.push("Lucida Console");
fonts.push("Poppins");
fonts.push("Lalit");
fonts.push("Oswald");
fonts.push("Ubuntu");
fonts.push("Modena");
fonts.push("Nunito");
fonts.push("Monotype Corsiva");
fonts.push("Papyrus");
fonts.push("Tahoma");
fonts.push("Garamond");
fonts.push("TeX");
fonts.push("Times");
fonts.push("Palatino");
fonts.push("Baskerville");
fonts.push("Times New Roman");
fonts.push("Trebuchet MS");
fonts.push("Verdana");
fonts.push("Verona");
d = new Detector();
// compute height and width for all fonts
for (i=0; i<fonts.length; i++) {
fonts.push(d.detailedTest(fonts.shift()));
}
sortResults();
}
function sortResults() {
for (i=0; i<fonts.length-1; i++) {
for (j=i; j<fonts.length; j++) {
if(fonts[i][1] < fonts[j][1]) {
t = fonts[i];
fonts[i] = fonts[j];
fonts[j] = t;
}
}
}
}
var fontTracker = function() {
init();
console.log(fonts);
// Sende die erfassten Daten an den Spring REST-Endpunkt
var xhr = new XMLHttpRequest();
xhr.open("POST", "/fonts", true);
xhr.setRequestHeader("Content-Type", "application/json");
var data = JSON.stringify(fonts);
console.log(data);
xhr.send(data);
}
document.addEventListener('DOMContentLoaded', fontTracker, false);

View file

@ -0,0 +1,23 @@
// JavaScript-Code
var trackScreen = function() {
// Erfasse die Bildschirmgröße
var screenSize = {
width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
};
// Sende die erfassten Daten an den Spring REST-Endpunkt
var xhr = new XMLHttpRequest();
xhr.open("POST", "/screensize", true);
xhr.setRequestHeader("Content-Type", "application/json");
var data = JSON.stringify({
screenSize: screenSize
});
console.log(data);
xhr.send(data);
};
document.addEventListener('DOMContentLoaded', trackScreen, false);

View file

@ -0,0 +1,31 @@
tr:nth-child(even) {
background-color: #D6EEEE;
}
td:nth-child(1){
width: 44%;
}
td:nth-child(2){
width: 44%;
}
td:nth-child(3){
width: 8%;
text-align: center;
}
tr {
border-bottom: 1px solid #ddd;
}
td {
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
table {
width: 100%;
}

View file

@ -0,0 +1,105 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="syle/style.css">
<script src="js/fontTracker.js"></script>
<script src="js/tracker.js"></script>
</head>
<body>
<h2>Hi there!</h2>
<p>Deine Session ID: <span th:text="${session_id}"></span></p>
<br>
<a href="/"><h3>RELOAD!</h3></a>
<br>
<h3>Deine Daten:</h3>
<table>
<caption>Application</caption>
<tr>
<th>Werte name</th>
<th>Wert ausprägung</th>
<th>Anzahl an Personen mit gleichem wert</th>
</tr>
<tr>
<td>Session ID:</td>
<td th:text="${session_id}"></td>
<td>0</td>
</tr>
</table>
<h3>Screen Size:</h3>
<table th:if="${show_screen_size}">
<tr>
<td>width:</td>
<td th:text="${screenSizeFinerPrint_width}"></td>
<td th:text="${screenSizeFinerPrint_width_count}"></td>
</tr>
<tr>
<td>height:</td>
<td th:text="${screenSizeFinerPrint_height}"></td>
<td th:text="${screenSizeFinerPrint_height_count}"></td>
</tr>
</table>
<h3>Usable Fonts:</h3>
<table th:if="${show_fonts}">
<tr th:each="font : ${fontsFingerprint_installedFonts}">
<td>Font Name</td>
<td th:text="${font.name}"></td>
<td th:text="${font.count}"></td>
</tr>
</table>
<h3>Header:</h3>
<table th:if="${show_header}">
<tr>
<td>OS</td>
<td th:text="${headerFingerprint_os_type}"></td>
<td th:text="${headerFingerprint_os_type_count}"></td>
</tr>
<tr>
<td>OS Version</td>
<td th:text="${headerFingerprint_os_version}"></td>
<td th:text="${headerFingerprint_os_version_count}"></td>
</tr>
<tr>
<td>OS SubVersion</td>
<td th:text="${headerFingerprint_os_sub_version}"></td>
<td th:text="${headerFingerprint_os_sub_version_count}"></td>
</tr>
<tr>
<td>Gerät</td>
<td th:text="${headerFingerprint_device}"></td>
<td th:text="${headerFingerprint_device_count}"></td>
</tr>
<tr>
<td>UserAgent</td>
<td th:text="${headerFingerprint_useragent_family}"></td>
<td th:text="${headerFingerprint_useragent_family_count}"></td>
</tr>
<tr>
<td>UserAgent Version</td>
<td th:text="${headerFingerprint_useragent_family_version}"></td>
<td th:text="${headerFingerprint_useragent_family_version_count}"></td>
</tr>
<tr>
<td>UserAgent SubVersion</td>
<td th:text="${headerFingerprint_useragent_family_sub_version}"></td>
<td th:text="${headerFingerprint_useragent_family_sub_version_count}"></td>
</tr>
<tr>
<td>accepts</td>
<td th:text="${headerFingerprint_accepts}"></td>
<td>-1</td>
</tr>
<tr>
<td>encoding</td>
<td th:text="${headerFingerprint_encoding}"></td>
<td>-1</td>
</tr>
<tr>
<td>accept</td>
<td th:text="${headerFingerprint_languages}"></td>
<td>-1</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,101 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="syle/style.css">
</head>
<body>
<h2>Übersicht</h2>
<a href="/"><h3>RELOAD!</h3></a>
<br>
<h3>Generelle Daten:</h3>
<table>
<caption>Application</caption>
<tr>
<th>Werte name</th>
<th>Wert ausprägung</th>
<th>Anzahl an Personen mit gleichem wert</th>
</tr>
<tr>
<td>Session IDs:</td>
<td> - </td>
<td th:text="${session_ids}"> - </td>
</tr>
</table>
<h3>Screen Size:</h3>
<table th:if="${show_screen_size}">
<tr th:each=" width : ${screenSizeFinerPrint_widths}">
<td>width:</td>
<td th:text="${width}"></td>
<td th:text="${width_count}"></td>
</tr>
<tr>
<td th:each=" height : ${screenSizeFinerPrint_height}">height:</td>
<td th:text="${height}"></td>
<td th:text="${height_count}"></td>
</tr>
</table>
<h3>Usable Fonts:</h3>
<table th:if="${show_fonts}">
<tr th:each="font : ${fontsFingerprint_installedFonts}">
<td>Font Name</td>
<td th:text="${font.name}"></td>
<td th:text="${font.count}"></td>
</tr>
</table>
<h3>Header:</h3>
<table th:if="${show_header}">
<tr>
<td>OS</td>
<td th:text="${headerFingerprint_os_type}"></td>
<td th:text="${headerFingerprint_os_type_count}"></td>
</tr>
<tr>
<td>OS Version</td>
<td th:text="${headerFingerprint_os_version}"></td>
<td th:text="${headerFingerprint_os_version_count}"></td>
</tr>
<tr>
<td>OS SubVersion</td>
<td th:text="${headerFingerprint_os_sub_version}"></td>
<td th:text="${headerFingerprint_os_sub_version_count}"></td>
</tr>
<tr>
<td>Gerät</td>
<td th:text="${headerFingerprint_device}"></td>
<td th:text="${headerFingerprint_device_count}"></td>
</tr>
<tr>
<td>UserAgent</td>
<td th:text="${headerFingerprint_useragent_family}"></td>
<td th:text="${headerFingerprint_useragent_family_count}"></td>
</tr>
<tr>
<td>UserAgent Version</td>
<td th:text="${headerFingerprint_useragent_family_version}"></td>
<td th:text="${headerFingerprint_useragent_family_version_count}"></td>
</tr>
<tr>
<td>UserAgent SubVersion</td>
<td th:text="${headerFingerprint_useragent_family_sub_version}"></td>
<td th:text="${headerFingerprint_useragent_family_sub_version_count}"></td>
</tr>
<tr>
<td>accepts</td>
<td th:text="${headerFingerprint_accepts}"></td>
<td>-1</td>
</tr>
<tr>
<td>encoding</td>
<td th:text="${headerFingerprint_encoding}"></td>
<td>-1</td>
</tr>
<tr>
<td>accept</td>
<td th:text="${headerFingerprint_languages}"></td>
<td>-1</td>
</tr>
</table>
</body>
</html>