diff --git a/build.gradle b/build.gradle index 58e161e..1701aa8 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,7 @@ dependencies { //JSON Parser implementation 'com.google.code.gson:gson:2.8.5' + compile 'com.googlecode.json-simple:json-simple:1.1.1' //compile 'org.springframework.boot:spring-boot-starter-tomcat' diff --git a/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java b/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java index 397ef33..3efc682 100644 --- a/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java +++ b/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java @@ -1,29 +1,25 @@ package hhn.labsw.bugageocaching.controller; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import hhn.labsw.bugageocaching.entities.*; -import hhn.labsw.bugageocaching.exceptions.IllegalParameterException; +import hhn.labsw.bugageocaching.helper.RankingListHelper; import hhn.labsw.bugageocaching.repositories.*; +import hhn.labsw.bugageocaching.util.FinderUtil; +import hhn.labsw.bugageocaching.util.VerificationUtil; import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.security.Keys; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.crypto.bcrypt.BCrypt; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; -import javax.xml.bind.DatatypeConverter; -import java.lang.reflect.Array; -import java.security.Key; -import java.security.SecureRandom; -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; + +import static hhn.labsw.bugageocaching.util.CacheConstructionUtil.createCacheUtil; +import static hhn.labsw.bugageocaching.util.CacheConstructionUtil.deleteCacheUtil; +import static hhn.labsw.bugageocaching.util.VerificationUtil.fetchPublicKey; @RestController public class Controller { @@ -49,13 +45,13 @@ public class Controller { @Autowired UserRepository userRepository; - private AtomicLong counter = new AtomicLong(); - byte[] key = new byte[64]; + @Autowired + User_InfoRepository user_infoRepository; + @PostConstruct public void init() { - new SecureRandom().nextBytes(key); - System.out.println(Arrays.toString(key)); + fetchPublicKey(); } @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @@ -65,253 +61,248 @@ public class Controller { return ResponseEntity.status(200).body(new Gson().toJson(cacheRepository.findAll())); } - @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose - @RequestMapping("/api/login") - @ResponseBody - public ResponseEntity login(@RequestBody User user) { - if (user.getUsername() == null || user.getPassword() == null) { - System.out.println(user.getUsername()); - System.out.println(user.getPassword()); - return ResponseEntity.status(400).body("Username or password cant be null"); - } - if (userRepository.findByUsername(user.getUsername()) == null) { - return ResponseEntity.status(404).body("User was not found"); - } - - SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; - - if (BCrypt.checkpw(user.getPassword(), userRepository.findByUsername(user.getUsername()).getPassword())) { - String token = Jwts.builder() - .setSubject(user.getUsername()) - .claim("admin", userRepository.findByUsername(user.getUsername()).getRoles().stream().anyMatch(x -> x.getId() == 0)) //True if user is admin - .setExpiration(new Date(new Date().getTime() + (1000 * 60 * 60 * 24))) //One day expiration - .signWith(signatureAlgorithm, key) - .compact(); - System.out.println(token); - - Claims claims = Jwts.parser() //Parse JWT - .setSigningKey(key) - .parseClaimsJws(token).getBody(); - System.out.println("ID: " + claims.getId()); - System.out.println("Subject: " + claims.getSubject()); - System.out.println("Issuer: " + claims.getIssuer()); - System.out.println("Admin: " + claims.get("admin")); - System.out.println("Expiration: " + claims.getExpiration()); - - return ResponseEntity.status(200).body(token); - } - - /*if (BCrypt.checkpw(user.getPassword(), userRepository.findByUsername(user.getUsername()).getPassword())) { - String token = user.getUsername() + BCrypt.hashpw(String.valueOf(System.currentTimeMillis() + counter.incrementAndGet()), BCrypt.gensalt()); - String hashedToken = BCrypt.hashpw(token, BCrypt.gensalt()); - userRepository.findByUsername(user.getUsername()).setToken(hashedToken); - userRepository.save(userRepository.findByUsername(user.getUsername())); - //return ResponseEntity.ok(new Gson().toJson(token)); - return ResponseEntity.status(200).body(token); - }*/ - return ResponseEntity.status(400).body("Es ist ein Fehler aufgetreten"); - } - + // user muss jetzt anders aus dem token geholt werden, da kein subject mehr gesetzt wird und username nichtmehr unique ist + // (über der checkAdmin methode steht ein möglicher lösungsvorschlag dafür) @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @RequestMapping("/api/startCache") @ResponseBody public ResponseEntity startCache(@RequestParam(value = "token", defaultValue = "-1") String token, - @RequestParam String cacheID) throws IllegalParameterException { + @RequestParam String cacheID) { if (!token.equals("-1")) { // ein angemeldeter user startet den cache(es werden zwei parameter übergeben) Bearbeitet bearbeitet = new Bearbeitet(); - try { - Claims claims = Jwts.parser() //Parse JWT - .setSigningKey(key) - .parseClaimsJws(token).getBody(); - User user = userRepository.findByUsername(claims.getSubject()); - if (user == null) { - return ResponseEntity.status(404).body("User was not found"); - } - bearbeitet.setUser(user); + //---------------------- + //Verify token + ResponseEntity tokenVerification = VerificationUtil.verifyToken(token); - Optional cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID)); - if (cacheOptional.isPresent()) { - Cache cache = cacheOptional.get(); - - if (bearbeitetRepository.findByUserAndCache(user, cache) != null) { - Bearbeitet bearbeitet1 = bearbeitetRepository.findByUserAndCache(user, cache); - return ResponseEntity.status(200).body(bearbeitet1); - } - - bearbeitet.setCache(cache); - - Station startStation = cache.getStationen().get(0); - bearbeitet.setAktuelleStation(startStation); - } else { - return ResponseEntity.status(404).body("Couldnt find Cache " + cacheID); - } - - Optional cacheAccesDefinitionOptional = - cacheAccesDefinitionRepository.findById(0); // angefangen - if (cacheAccesDefinitionOptional.isPresent()) { - CacheAccesDefinition cacheAccesDefinition = cacheAccesDefinitionOptional.get(); - bearbeitet.setCacheAccesDefinition(cacheAccesDefinition); - } else { - return ResponseEntity.status(404).body("There is no cacheAccesDefinition with the ID " + 0); - } - - bearbeitetRepository.save(bearbeitet); - - return ResponseEntity.status(201).body(new Gson().toJson(bearbeitet)); - } catch (ExpiredJwtException e) { - return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e) { - return ResponseEntity.status(400).body("JWT Token invalid"); + //Error in token verification + if (tokenVerification.getStatusCodeValue() != 200) { + return tokenVerification; } + Claims claims = (Claims) tokenVerification.getBody(); + + + //Sollte jetzt eigentlich funktionieren...hoffe ich + ResponseEntity getUser = FinderUtil.findUserFromClaim(claims); + + if (getUser.getStatusCodeValue() != 200) { + return getUser; + } + + User user = (User) getUser.getBody(); + + bearbeitet.setUser(user); + + //---------------------- + //Get Cache + ResponseEntity getCache = FinderUtil.findCacheById(cacheID); + + if (getCache.getStatusCodeValue() != 200) { + return getCache; + } + + Cache cache = (Cache) getCache.getBody(); + //---------------------- + + if (bearbeitetRepository.findByUserAndCache(user, cache) != null) { + Bearbeitet bearbeitet1 = bearbeitetRepository.findByUserAndCache(user, cache); + return ResponseEntity.status(200).body(bearbeitet1); + } + + bearbeitet.setCache(cache); + + Station startStation = cache.getStationen().get(0); + bearbeitet.setAktuelleStation(startStation); + + + Optional cacheAccesDefinitionOptional = + cacheAccesDefinitionRepository.findById(0); // angefangen + if (cacheAccesDefinitionOptional.isPresent()) { + CacheAccesDefinition cacheAccesDefinition = cacheAccesDefinitionOptional.get(); + bearbeitet.setCacheAccesDefinition(cacheAccesDefinition); + } else { + return ResponseEntity.status(404).body("There is no cacheAccesDefinition with the ID " + 0); + } + + bearbeitetRepository.save(bearbeitet); + + return ResponseEntity.status(201).body(new Gson().toJson(bearbeitet)); + } else { // kein angemeldeter User startet den cache(es wird nur der cache als parameter übergeben) - Optional cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID)); - if (cacheOptional.isPresent()) { - Cache cache = cacheOptional.get(); - return ResponseEntity.status(200).body(new Gson().toJson(cache)); - } else { - return ResponseEntity.status(404).body("Couldnt find Cache " + cacheID); + + ResponseEntity getCache = FinderUtil.findCacheById(cacheID); + + if (getCache.getStatusCodeValue() != 200) { + return getCache; } + + Cache cache = (Cache) getCache.getBody(); + + return ResponseEntity.status(200).body(new Gson().toJson(cache)); } } - //Eigentlich brauchen wir mit JWT keine Logout Methode mehr. + //user muss jetzt anders aus dem token geholt werden, da kein subject mehr gesetzt wird und username nichtmehr unique ist @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose - @RequestMapping("/api/logout") + @RequestMapping("/api/checkStation") @ResponseBody - public ResponseEntity logout(@RequestParam String token) { -// System.out.println("logout"); - /*User user = userRepository.findByUsername(token.substring(0, token.indexOf("$"))); -// System.out.println(token); -// System.out.println(user.getToken()); - if (user == null || user.getToken().isEmpty()) { - return ResponseEntity.status(404).body("User was not found"); + public ResponseEntity checkStation(@RequestParam String token, + @RequestParam String cacheID, + @RequestParam String stationID, + @RequestParam String durchgefuehrterCacheID) { + //---------------------- + //Verify token + ResponseEntity tokenVerification = VerificationUtil.verifyToken(token); + + //Error in token verification + if (tokenVerification.getStatusCodeValue() != 200) { + return tokenVerification; } - user.setToken(null); - userRepository.save(user);*/ - return ResponseEntity.status(200).body("Token was deleted"); + + Claims claims = (Claims) tokenVerification.getBody(); + + + ResponseEntity getUser = FinderUtil.findUserFromClaim(claims); + + if (getUser.getStatusCodeValue() != 200) { + return getUser; + } + + User user = (User) getUser.getBody(); + //---------------------- + + //---------------------- + //Get Cache + ResponseEntity getCache = FinderUtil.findCacheById(cacheID); + + if (getCache.getStatusCodeValue() != 200) { + return getCache; + } + + Cache cache = (Cache) getCache.getBody(); + //---------------------- + + //---------------------- + //Get durchgeführter Cache + ResponseEntity getDurchgefuehrterCache = FinderUtil.findCacheById(durchgefuehrterCacheID); + + if (getDurchgefuehrterCache.getStatusCodeValue() != 200) { + return getDurchgefuehrterCache; + } + + Cache durchgefuehrterCache = (Cache) getDurchgefuehrterCache.getBody(); + //---------------------- + + //---------------------- + //Get Station + ResponseEntity getStation = FinderUtil.findStationById(stationID); + + if (getStation.getStatusCodeValue() != 200) { + return getStation; + } + + Station station = (Station) getStation.getBody(); + //---------------------- + + if (cache != durchgefuehrterCache) { + return ResponseEntity.status(400).body("The scanned station isn´t the correct following station"); + } + + //---------------------- + //Get Bearbeitet entry + ResponseEntity getBearbeitet = FinderUtil.findBearbeitetByUserAndCache(user, cache); + + if (getBearbeitet.getStatusCodeValue() != 200) { + return getBearbeitet; + } + + Bearbeitet bearbeitet = (Bearbeitet) getBearbeitet.getBody(); + //---------------------- + + + Station aktuelleStation = bearbeitet.getAktuelleStation(); + if (aktuelleStation == null) { + return ResponseEntity.status(400).body("Database Error"); + } + + if (!cache.getStationen().contains(station)) { + return ResponseEntity.status(400).body("The scanned station isnt a part of the cache"); + } + + int i = cache.getStationen().indexOf(station); + + + if (cache.getStationen().get(i - 1).equals(aktuelleStation)) { + bearbeitet.setAktuelleStation(station); + if (i == cache.getStationen().size() - 1) { // letze Station erreicht + //---------------------- + //Get CacheAccesDefinition + ResponseEntity getCacheAccesDefinition = FinderUtil.findCacheAccesDefinitionById("1"); + + if (getCacheAccesDefinition.getStatusCodeValue() != 200) { + return getCacheAccesDefinition; + } + + CacheAccesDefinition cacheAccesDefinition = (CacheAccesDefinition) getCacheAccesDefinition.getBody(); + //---------------------- + bearbeitet.setCacheAccesDefinition(cacheAccesDefinition); + //Get User_Info + ResponseEntity getUser_Info = FinderUtil.findUser_InfoByID(String.valueOf(user.getId())); + + if (getUser_Info.getStatusCodeValue() != 200) { + return getUser_Info; + } + + User_Info user_info = (User_Info) getUser_Info.getBody(); + //---------------------- + user_info.setRankingPointsSum(user_info.getRankingPointsSum() + cache.getRankingPoints()); + user_infoRepository.save(user_info); + bearbeitetRepository.save(bearbeitet); + } + return ResponseEntity.status(200).body(new Gson().toJson(bearbeitet)); + } else { + return ResponseEntity.status(400).body("The scanned station isn´t the correct following station"); + } + } @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @RequestMapping("/api/createCache") @ResponseBody public ResponseEntity createCache(@RequestBody Cache cache) { - System.out.println(cache.getName()); - System.out.println(cache.getStationen().size()); -// System.out.println(cache.getStationen().get(0).getId()); - // Stationen werden in die Datenbank eingetragen - for (Station station : cache.getStationen()) { - ResponseEntity response = createStation(station); - if (response.getStatusCodeValue() == 400) { - deleteStationen(cache); - return response; - } - } - System.out.println("Stationen eingetragen!"); - // Caches werden in die Datenbank eingetragen - if (cache.getDescription().length() == 0 || cache.getName().length() == 0 || cache.getRankingPoints() == 0.0 || cache.getStationen().size() < 2) { - deleteStationen(cache); - return ResponseEntity.status(400).body("cache fields can´t be empty"); - } - - for (Cache cache1 : cacheRepository.findAll()) { - if (cache1.getName().equals(cache.getName())) { - deleteStationen(cache); - return ResponseEntity.status(400).body("name is already taken"); - } - } - - if (cache.getRankingPoints() < 0) { - deleteStationen(cache); - return ResponseEntity.status(400).body("Ranking points has to be a positive number"); - } - - cacheRepository.save(cache); - - return ResponseEntity.status(200).body(new Gson().toJson(cache)); + return createCacheUtil(cache); } - public ResponseEntity createStation(Station station) { - - if (station.getDescription().length() == 0 || station.getLattitude() == 0.0 || station.getLongitude() == 0.0 /*|| station.getSolution().length() == 0*/) { - return ResponseEntity.status(400).body("station fields can´t be empty"); - } - - if (station.getLattitude() < -90 || station.getLattitude() > 90) { - return ResponseEntity.status(400).body("Lattitude has to be between -90 and 90 Degree"); - } - - if (station.getLongitude() < -180 || station.getLongitude() > 180) { - return ResponseEntity.status(400).body("Longitude has to be in the range of -180 to 180 degrees"); - } - - Random r = new Random(); - int low = 100000; - int high = 1000000; - int code = 0; - boolean unique = false; - while (!unique) { - code = r.nextInt(high - low) + low; - unique = true; - for (Station station1 : stationRepository.findAll()) { - if (station1.getCode() == code) { - unique = false; - } - } - } - - station.setCode(code); - - stationRepository.save(station); - - return ResponseEntity.status(200).body(new Gson().toJson(station)); - } - - public void deleteStationen(Cache cache) { - for (Station station : cache.getStationen()) { - try { - stationRepository.delete(station); - } catch (IllegalArgumentException e) { // station is null - // do nothing - } - } - } - - @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @RequestMapping("/api/checkAdmin") @ResponseBody public ResponseEntity checkAdmin(@RequestParam String token) { - try { - Claims claims = Jwts.parser() //Parse JWT - .setSigningKey(key) - .parseClaimsJws(token).getBody(); + ResponseEntity verifyToken = VerificationUtil.verifyToken(token); - return ResponseEntity.status(200).body(claims.get("admin")); - } catch (ExpiredJwtException e) { - return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e) { - return ResponseEntity.status(400).body("JWT Token invalid"); + if (verifyToken.getStatusCodeValue() != 200) { + return verifyToken; } - /*User user = userRepository.findByUsername(token.substring(0, token.indexOf("$"))); - if (user == null) { - return ResponseEntity.status(404).body("User was not found"); + Claims claims = (Claims) verifyToken.getBody(); + + ResponseEntity userResponse = FinderUtil.findUserFromClaim(claims); + + if(userResponse.getStatusCodeValue() != 200){ + return userResponse; } - for (Role role : user.getRoles()) { - if (role.getId() == 0) { // is admin - return ResponseEntity.status(200).body("User is Admin"); - } - } - return ResponseEntity.status(401).body("User is no Admin");*/ + + User user = (User) userResponse.getBody(); + + //TODO Hier Admin Check einfügen + + return ResponseEntity.status(200).body(claims.get("admin")); } - //Bis hier @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @RequestMapping("/api/getAllStations") @ResponseBody @@ -323,81 +314,59 @@ public class Controller { @RequestMapping("/api/deleteCache") @ResponseBody public ResponseEntity deleteCache(@RequestParam String cacheID) { - Optional optionalCache = cacheRepository.findById(Integer.valueOf(cacheID)); - if (!optionalCache.isPresent()) { - return ResponseEntity.status(404).body(new Gson().toJson("There is no cache with the ID " + cacheID)); - } - - Cache cache = optionalCache.get(); - - for (Bearbeitet bearbeitet : bearbeitetRepository.findAll()) { - if (bearbeitet.getCache().getId() == cache.getId()) { - bearbeitetRepository.delete(bearbeitet); - } - } - - ArrayList stationen = new ArrayList<>(); - for (Station station : cache.getStationen()) { - stationen.add(stationRepository.findById(station.getId()).get()); - } - - cacheRepository.delete(cache); - - for (Station station : stationen) { - stationRepository.delete(station); - } - - - return ResponseEntity.status(200).body(new Gson().toJson(true)); + return deleteCacheUtil(cacheID); } + @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @RequestMapping("/api/getMyCaches") @ResponseBody public ResponseEntity getMyCaches(@RequestParam String token) { - try { - - Claims claims = Jwts.parser() //Parse JWT - .setSigningKey(key) - .parseClaimsJws(token).getBody(); - User user = userRepository.findByUsername(claims.getSubject()); + ResponseEntity verifyToken = VerificationUtil.verifyToken(token); - if (user != null) { - ArrayList bearbeitetList = new ArrayList<>(); + if (verifyToken.getStatusCodeValue() != 200) { + return verifyToken; + } - for (Bearbeitet bearbeitet : bearbeitetRepository.findAll()) { - if (bearbeitet.getUser().getId() == user.getId()) { - bearbeitetList.add(bearbeitet); - } + Claims claims = (Claims) verifyToken.getBody(); + + ResponseEntity getUser = FinderUtil.findUserFromClaim(claims); + + if (getUser.getStatusCodeValue() != 200) { + return getUser; + } + + User user = (User) getUser.getBody(); + + if (user != null) { + ArrayList bearbeitetList = new ArrayList<>(); + + for (Bearbeitet bearbeitet : bearbeitetRepository.findAll()) { + if (bearbeitet.getUser().getId() == user.getId()) { + bearbeitetList.add(bearbeitet); } - return ResponseEntity.status(200).body(new Gson().toJson(bearbeitetList)); - } else { - return ResponseEntity.status(404).body("User was not found in the database"); } - } catch (ExpiredJwtException e) { - return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e) { - return ResponseEntity.status(400).body("JWT Token invalid"); + return ResponseEntity.status(200).body(new Gson().toJson(bearbeitetList)); + } else { + return ResponseEntity.status(404).body("User was not found in the database"); } } + // Ich hab mal eine Hilfsklasse erstellt, damit die Daten in einer schöneren Form ins Frontend kommen und da quasi nichts geändert + // werden muss. Ich konnte es noch nicht ausprobieren, da die se server down sind (11:05 Uhr) @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @RequestMapping("/api/getRankingList") @ResponseBody public ResponseEntity getRankingList() { - List sendBackUsers = new LinkedList<>(); + List sendBackUsers = new LinkedList<>(); List rankingUsers = userRepository.getRankingList(); for (Object[] obj : rankingUsers) { - User u = new User(); - u.setId((int) obj[0]); - u.setUsername((String) obj[1]); - u.setRankingPointsSum((int) obj[2]); - sendBackUsers.add(u); + RankingListHelper tmp = new RankingListHelper((String) obj[1], (int) obj[2]); + sendBackUsers.add(tmp); } - return ResponseEntity.status(200).body(new Gson().toJson(sendBackUsers)); } @@ -405,23 +374,29 @@ public class Controller { @RequestMapping("/api/getUser") @ResponseBody public ResponseEntity getUser(@RequestParam String token) { - try { - Claims claims = Jwts.parser() //Parse JWT - .setSigningKey(key) - .parseClaimsJws(token).getBody(); + ResponseEntity verifyToken = VerificationUtil.verifyToken(token); - User user = userRepository.findByUsername(claims.getSubject()); - if (user != null) { - return ResponseEntity.status(200).body(new Gson().toJson(user)); - } else { - return ResponseEntity.status(404).body("User was not found in the database"); - } - } catch (ExpiredJwtException e) { - return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e) { - return ResponseEntity.status(400).body("JWT Token invalid"); + if (verifyToken.getStatusCodeValue() != 200) { + return verifyToken; + } + + Claims claims = (Claims) verifyToken.getBody(); + + ResponseEntity getUser = FinderUtil.findUserFromClaim(claims); + + if (getUser.getStatusCodeValue() != 200) { + return getUser; + } + + User user = (User) getUser.getBody(); + + if (user != null) { + return ResponseEntity.status(200).body(new Gson().toJson(user)); + } else { + return ResponseEntity.status(404).body("User was not found in the database"); } } } + diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/Bearbeitet.java b/src/main/java/hhn/labsw/bugageocaching/entities/Bearbeitet.java index f046d84..8b1f3dc 100644 --- a/src/main/java/hhn/labsw/bugageocaching/entities/Bearbeitet.java +++ b/src/main/java/hhn/labsw/bugageocaching/entities/Bearbeitet.java @@ -2,6 +2,7 @@ package hhn.labsw.bugageocaching.entities; import javax.persistence.*; +import javax.validation.constraints.NotNull; @Entity @Table diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/Role.java b/src/main/java/hhn/labsw/bugageocaching/entities/Role.java index b5612bc..3e4a9c5 100644 --- a/src/main/java/hhn/labsw/bugageocaching/entities/Role.java +++ b/src/main/java/hhn/labsw/bugageocaching/entities/Role.java @@ -11,6 +11,7 @@ public class Role { @GeneratedValue private int id; private String name; + private String domain; public Role() { @@ -32,6 +33,14 @@ public class Role { this.name = name; } + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + @Override public String toString() { return name; diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/Station.java b/src/main/java/hhn/labsw/bugageocaching/entities/Station.java index fe1344f..31bc0eb 100644 --- a/src/main/java/hhn/labsw/bugageocaching/entities/Station.java +++ b/src/main/java/hhn/labsw/bugageocaching/entities/Station.java @@ -2,6 +2,7 @@ package hhn.labsw.bugageocaching.entities; import javax.persistence.*; +import javax.validation.constraints.NotNull; @Entity @Table @@ -11,10 +12,20 @@ public class Station { @GeneratedValue private int id; + @NotNull private String description; + + @NotNull private double longitude; + + @NotNull private double lattitude; + + @Column(unique = true) + @NotNull private int code; + + @NotNull private String solution; public Station() { diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/User.java b/src/main/java/hhn/labsw/bugageocaching/entities/User.java index 0b546f6..656a7f3 100644 --- a/src/main/java/hhn/labsw/bugageocaching/entities/User.java +++ b/src/main/java/hhn/labsw/bugageocaching/entities/User.java @@ -12,13 +12,10 @@ import java.util.List; public class User { @Id - @GeneratedValue private int id; - private String firstname; - private String lastname; private String username; - private int rankingPointsSum; + private String email; private String password; @@ -26,10 +23,6 @@ public class User { @ManyToMany private List roles; - @ManyToOne - private Team team; - - @Transient private String passwordConfirm; @@ -41,22 +34,6 @@ public class User { this.id = id; } - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - public String getLastname() { - return lastname; - } - - public void setLastname(String lastname) { - this.lastname = lastname; - } - public String getUsername() { return username; } @@ -65,14 +42,6 @@ public class User { this.username = username; } - public int getRankingPointsSum() { - return rankingPointsSum; - } - - public void setRankingPointsSum(int rankingPointsSum) { - this.rankingPointsSum = rankingPointsSum; - } - public String getEmail() { return email; } @@ -89,14 +58,6 @@ public class User { this.password = password; } - public Team getTeam() { - return team; - } - - public void setTeam(Team team) { - this.team = team; - } - public List getRoles() { return roles; } diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/User_Info.java b/src/main/java/hhn/labsw/bugageocaching/entities/User_Info.java new file mode 100644 index 0000000..74ff0a3 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/entities/User_Info.java @@ -0,0 +1,50 @@ +package hhn.labsw.bugageocaching.entities; + +import org.springframework.context.annotation.Primary; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +@Table +@IdClass(User_InfoID.class) +public class User_Info implements Serializable { + + @Id + @OneToOne + private User user; + + @Id + private int rankingPointsSum; + + @ManyToOne + private Team team; + + + public User_Info() { + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public int getRankingPointsSum() { + return rankingPointsSum; + } + + public void setRankingPointsSum(int rankingPointsSum) { + this.rankingPointsSum = rankingPointsSum; + } + + public Team getTeam() { + return team; + } + + public void setTeam(Team team) { + this.team = team; + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/User_InfoID.java b/src/main/java/hhn/labsw/bugageocaching/entities/User_InfoID.java new file mode 100644 index 0000000..4d63e41 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/entities/User_InfoID.java @@ -0,0 +1,8 @@ +package hhn.labsw.bugageocaching.entities; + +import java.io.Serializable; + +public class User_InfoID implements Serializable { + private int user; + private int rankingPointsSum; +} diff --git a/src/main/java/hhn/labsw/bugageocaching/fetchObjects/PublicKey.java b/src/main/java/hhn/labsw/bugageocaching/fetchObjects/PublicKey.java new file mode 100644 index 0000000..198ccca --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/fetchObjects/PublicKey.java @@ -0,0 +1,13 @@ +package hhn.labsw.bugageocaching.fetchObjects; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class PublicKey { + + private String message; + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/helper/RankingListHelper.java b/src/main/java/hhn/labsw/bugageocaching/helper/RankingListHelper.java new file mode 100644 index 0000000..13f474a --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/helper/RankingListHelper.java @@ -0,0 +1,28 @@ +package hhn.labsw.bugageocaching.helper; + +public class RankingListHelper { + + private String username; + private int ranking_Points; + + public RankingListHelper(String username, int ranking_Points) { + this.username = username; + this.ranking_Points = ranking_Points; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public int getRanking_Points() { + return ranking_Points; + } + + public void setRanking_Points(int ranking_Points) { + this.ranking_Points = ranking_Points; + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java index 8ab2115..d502743 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java @@ -14,7 +14,10 @@ import java.util.List; public interface UserRepository extends CrudRepository { User findByUsername(String username); - @Query(value = "SELECT u.id, u.username, u.ranking_points_sum from user u order by ranking_points_sum DESC", nativeQuery = true) + @Query(value = "SELECT u.id AS ID, SUBSTRING_INDEX(u.email, '@', 1) AS Name, ui.ranking_points_sum AS Ranglistenpunkte\n" + + "FROM user u, user_info ui\n" + + "WHERE u.id = ui.user_id\n" + + "order by ranking_points_sum DESC", nativeQuery = true) List getRankingList(); } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/User_InfoRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/User_InfoRepository.java new file mode 100644 index 0000000..a96b12d --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/User_InfoRepository.java @@ -0,0 +1,8 @@ +package hhn.labsw.bugageocaching.repositories; + +import hhn.labsw.bugageocaching.entities.User_Info; +import org.springframework.data.repository.CrudRepository; + +public interface User_InfoRepository extends CrudRepository { + +} diff --git a/src/main/java/hhn/labsw/bugageocaching/util/CacheConstructionUtil.java b/src/main/java/hhn/labsw/bugageocaching/util/CacheConstructionUtil.java new file mode 100644 index 0000000..ee2fd03 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/util/CacheConstructionUtil.java @@ -0,0 +1,141 @@ +package hhn.labsw.bugageocaching.util; + +import com.google.gson.Gson; +import hhn.labsw.bugageocaching.entities.Bearbeitet; +import hhn.labsw.bugageocaching.entities.Cache; +import hhn.labsw.bugageocaching.entities.Station; +import hhn.labsw.bugageocaching.repositories.BearbeitetRepository; +import hhn.labsw.bugageocaching.repositories.CacheRepository; +import hhn.labsw.bugageocaching.repositories.StationRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; + +import javax.persistence.RollbackException; +import java.util.ArrayList; +import java.util.Optional; +import java.util.Random; + +public class CacheConstructionUtil { + + @Autowired + static StationRepository stationRepository; + + @Autowired + static CacheRepository cacheRepository; + + @Autowired + static BearbeitetRepository bearbeitetRepository; + + public static ResponseEntity createCacheUtil(Cache cache) { + + // Stationen werden in die Datenbank eingetragen + for (Station station : cache.getStationen()) { + ResponseEntity response = createStationUtil(station); + if (response.getStatusCodeValue() == 400) { + deleteStationenUtil(cache); + return response; + } + } + + // Caches werden in die Datenbank eingetragen + if (cache.getDescription().length() == 0 || cache.getName().length() == 0 || cache.getRankingPoints() == 0.0 || cache.getStationen().size() == 0) { + deleteStationenUtil(cache); + return ResponseEntity.status(400).body("cache fields can´t be empty"); + } + + for (Cache cache1 : cacheRepository.findAll()) { + if (cache1.getName().equals(cache.getName())) { + deleteStationenUtil(cache); + return ResponseEntity.status(400).body("name is already taken"); + } + } + + if (cache.getRankingPoints() < 0) { + deleteStationenUtil(cache); + return ResponseEntity.status(400).body("Ranking points has to be a positive number"); + } + + cacheRepository.save(cache); + + return ResponseEntity.status(200).body(new Gson().toJson(cache)); + } + + public static ResponseEntity createStationUtil(Station station) { + + if (station.getDescription().length() == 0 || station.getLattitude() == 0.0 || station.getLongitude() == 0.0 || station.getSolution().length() == 0) { + return ResponseEntity.status(400).body("station fields can´t be empty"); + } + + if (station.getLattitude() < -90 || station.getLattitude() > 90) { + return ResponseEntity.status(400).body("Lattitude has to be between -90 and 90 Degree"); + } + + if (station.getLongitude() < -180 || station.getLongitude() > 180) { + return ResponseEntity.status(400).body("Longitude has to be in the range of -180 to 180 degrees"); + } + + Random r = new Random(); + int low = 100000; + int high = 1000000; + int code = 0; + boolean unique = false; + + while (!unique) { + code = r.nextInt(high - low) + low; + unique = true; + for (Station station1 : stationRepository.findAll()) { + if (station1.getCode() == code) { + unique = false; + } + } + } + + try { + station.setCode(code); + } catch (RollbackException e) { + return ResponseEntity.status(400).body("There was an error generating the unique code"); + } + + stationRepository.save(station); + + return ResponseEntity.status(200).body(new Gson().toJson(station)); + } + + public static void deleteStationenUtil(Cache cache) { + for (Station station : cache.getStationen()) { + try { + stationRepository.delete(station); + } catch (IllegalArgumentException e) { // station is null + // do nothing + } + } + } + + public static ResponseEntity deleteCacheUtil(String cacheID) { + Optional optionalCache = cacheRepository.findById(Integer.valueOf(cacheID)); + if (!optionalCache.isPresent()) { + return ResponseEntity.status(404).body(new Gson().toJson("There is no cache with the ID " + cacheID)); + } + + Cache cache = optionalCache.get(); + + for (Bearbeitet bearbeitet : bearbeitetRepository.findAll()) { + if (bearbeitet.getCache().getId() == cache.getId()) { + bearbeitetRepository.delete(bearbeitet); + } + } + + ArrayList stationen = new ArrayList<>(); + for (Station station : cache.getStationen()) { + stationen.add(stationRepository.findById(station.getId()).get()); + } + + cacheRepository.delete(cache); + + for (Station station : stationen) { + stationRepository.delete(station); + } + + return ResponseEntity.status(200).body(new Gson().toJson(true)); + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/util/FinderUtil.java b/src/main/java/hhn/labsw/bugageocaching/util/FinderUtil.java new file mode 100644 index 0000000..26aa0a7 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/util/FinderUtil.java @@ -0,0 +1,119 @@ +package hhn.labsw.bugageocaching.util; + +import hhn.labsw.bugageocaching.entities.*; +import hhn.labsw.bugageocaching.repositories.*; +import io.jsonwebtoken.Claims; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; + +import java.util.Optional; + +public class FinderUtil { + + @Autowired + static CacheRepository cacheRepository; + + @Autowired + static RewardRepository rewardRepository; + + @Autowired + static StationRepository stationRepository; + + @Autowired + static BearbeitetRepository bearbeitetRepository; + + @Autowired + static CacheAccesDefinitionRepository cacheAccesDefinitionRepository; + + @Autowired + static TeamRepository teamRepository; + + @Autowired + static UserRepository userRepository; + + @Autowired + static User_InfoRepository user_infoRepository; + + public static ResponseEntity findCacheById(String cacheID) { + + Optional cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID)); + if (cacheOptional.isPresent()) { + return ResponseEntity.status(200).body(cacheOptional.get()); + } else { + return ResponseEntity.status(404).body("Couldnt find Cache " + cacheID); + } + } + + public static ResponseEntity findStationById(String stationID) { + + Optional stationOptional = stationRepository.findById(Integer.valueOf(stationID)); + if (stationOptional.isPresent()) { + return ResponseEntity.status(200).body(stationOptional.get()); + } else { + return ResponseEntity.status(404).body("Couldnt find Station " + stationID); + } + } + + public static ResponseEntity findBearbeitetByUserAndCache(User user, Cache cache) { + + Bearbeitet bearbeitet = bearbeitetRepository.findByUserAndCache(user, cache); + + if (bearbeitet != null) { + return ResponseEntity.status(200).body(bearbeitet); + } + + return ResponseEntity.status(404).body("The user has not started this cache yet"); + } + + public static ResponseEntity findUserByUsername(String username) { + + User user = userRepository.findByUsername(username); + if (user != null) { + return ResponseEntity.status(200).body(user); + } + + return ResponseEntity.status(404).body("Couldnt find user with username " + username); + } + + public static ResponseEntity findCacheAccesDefinitionById(String cacheAccesDefinitionID) { + Optional cacheAccesDefinitionOptional = cacheAccesDefinitionRepository.findById(Integer.valueOf(cacheAccesDefinitionID)); + if (cacheAccesDefinitionOptional.isPresent()) { + return ResponseEntity.status(200).body(cacheAccesDefinitionOptional.get()); + } else { + return ResponseEntity.status(404).body("Couldnt find CacheAccesDefinition " + cacheAccesDefinitionID); + } + } + + public static ResponseEntity findUser_InfoByID(String infoID) { + Optional user_InfoOptional = user_infoRepository.findById(Integer.valueOf(infoID)); + if (user_InfoOptional.isPresent()) { + return ResponseEntity.status(200).body(user_InfoOptional.get()); + } else { + return ResponseEntity.status(404).body("Couldnt find User_Info " + infoID); + } + } + + public static ResponseEntity findUserFromClaim(Claims claims) { + + try { + String userString = (String) claims.get("user"); + JSONParser parser = new JSONParser(); + JSONObject userObject = (JSONObject) parser.parse(userString); + int userID = (Integer) userObject.get("userID"); + Optional userOptional = userRepository.findById(userID); + if (userOptional.isPresent()) { + User user = userOptional.get(); + return ResponseEntity.status(200).body(user); + } else { + return ResponseEntity.status(404).body("Couldnt find User " + userID); + } + } catch (ParseException e) { + e.printStackTrace(); + return ResponseEntity.status(404).body("String format was corrupt"); + } + } + + } diff --git a/src/main/java/hhn/labsw/bugageocaching/util/VerificationUtil.java b/src/main/java/hhn/labsw/bugageocaching/util/VerificationUtil.java new file mode 100644 index 0000000..b29ae41 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/util/VerificationUtil.java @@ -0,0 +1,51 @@ +package hhn.labsw.bugageocaching.util; + +import hhn.labsw.bugageocaching.fetchObjects.PublicKey; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +import java.security.Key; +import java.security.KeyFactory; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class VerificationUtil { + + public static Key publicKey; + + public static void fetchPublicKey() { + RestTemplate restTemplate = new RestTemplate(); + try { + PublicKey response = restTemplate.getForObject("http://seserver.se.hs-heilbronn.de:8090/buga19usermanagement/token/publickey", PublicKey.class); + byte[] decodedKey = Base64.getDecoder().decode(response.getMessage()); + KeyFactory factory = KeyFactory.getInstance("RSA"); + X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(decodedKey); + Key key = factory.generatePublic(publicKeySpec); + + publicKey = key; + } catch (Exception e) { + e.printStackTrace(); + } + + //Fehler muss zurückgegeben werden + } + + public static ResponseEntity verifyToken(String token){ + + try{ + Claims claims = Jwts.parser() //Parse JWT + .setSigningKey(VerificationUtil.publicKey) + .parseClaimsJws(token).getBody(); + + return ResponseEntity.status(200).body(claims); + } catch (ExpiredJwtException e){ + return ResponseEntity.status(401).body("JWT Token expired"); + } catch (Exception e){ + return ResponseEntity.status(400).body("Something went wrong"); + } + } +}