diff --git a/pom.xml b/pom.xml index 135051b..2d6805f 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,51 @@ spring-boot-starter-test test + + + org.springframework.boot + spring-boot-starter-security + + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.projectlombok + lombok + provided + + + org.springframework.boot + spring-boot-starter + diff --git a/src/main/java/com/example/hangry/GroupController.java b/src/main/java/com/example/hangry/GroupController.java deleted file mode 100644 index fb3434e..0000000 --- a/src/main/java/com/example/hangry/GroupController.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.hangry; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import java.util.Set; - -@RestController -@RequestMapping("/api/groups") -@CrossOrigin(origins = "*") -public class GroupController { - - private final GroupService groupService; - - public GroupController(GroupService groupService) { - this.groupService = groupService; - } - - // Neue Gruppe erstellen - @PostMapping - public ResponseEntity createGroup(@RequestParam String name, @RequestParam String description) { - return ResponseEntity.ok(groupService.createGroup(name, description)); - } - - // Gruppe beitreten - @PostMapping("/{groupId}/join/{userId}") - public ResponseEntity joinGroup(@PathVariable Long groupId, @PathVariable Long userId) { - boolean joined = groupService.joinGroup(userId, groupId); - return joined ? ResponseEntity.ok("Gruppe beigetreten") : ResponseEntity.badRequest().body("Bereits Mitglied"); - } - - // Gruppe verlassen - @PostMapping("/{groupId}/leave/{userId}") - public ResponseEntity leaveGroup(@PathVariable Long groupId, @PathVariable Long userId) { - boolean left = groupService.leaveGroup(userId, groupId); - return left ? ResponseEntity.ok("Gruppe verlassen") : ResponseEntity.badRequest().body("Nicht in der Gruppe"); - } - - // Mitglieder einer Gruppe abrufen - @GetMapping("/{groupId}/members") - public ResponseEntity> getGroupMembers(@PathVariable Long groupId) { - return ResponseEntity.ok(groupService.getGroupMembers(groupId)); - } -} diff --git a/src/main/java/com/example/hangry/GroupRecipeController.java b/src/main/java/com/example/hangry/GroupRecipeController.java deleted file mode 100644 index 9965fec..0000000 --- a/src/main/java/com/example/hangry/GroupRecipeController.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.hangry; - - - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.Set; - - -@RestController -@RequestMapping("/api/group-recipes") -@CrossOrigin(origins = "*") -public class GroupRecipeController { - - private final GroupRecipeService groupRecipeService; - - public GroupRecipeController(GroupRecipeService groupRecipeService) { - this.groupRecipeService = groupRecipeService; - } - - @PostMapping("/{groupId}/share/{recipeId}") - public ResponseEntity shareRecipe(@PathVariable Long groupId, @PathVariable Long recipeId) { - boolean shared = groupRecipeService.shareRecipeWithGroup(groupId, recipeId); - return shared ? ResponseEntity.ok("Rezept geteilt") : ResponseEntity.badRequest().body("Fehler beim Teilen"); - } - - @GetMapping("/{groupId}") - public ResponseEntity> getGroupRecipes(@PathVariable Long groupId) { - return ResponseEntity.ok(groupRecipeService.getGroupRecipes(groupId)); - } -} diff --git a/src/main/java/com/example/hangry/GroupRecipeService.java b/src/main/java/com/example/hangry/GroupRecipeService.java deleted file mode 100644 index be8fb4e..0000000 --- a/src/main/java/com/example/hangry/GroupRecipeService.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example.hangry; - -import org.springframework.stereotype.Service; -import java.util.Set; -import java.util.stream.Collectors; - -@Service -public class GroupRecipeService { - - private final GroupRepository groupRepository; - private final RecipeRepository recipeRepository; - private final GroupRecipeRepository groupRecipeRepository; - - public GroupRecipeService(GroupRepository groupRepository, RecipeRepository recipeRepository, GroupRecipeRepository groupRecipeRepository) { - this.groupRepository = groupRepository; - this.recipeRepository = recipeRepository; - this.groupRecipeRepository = groupRecipeRepository; - } - - // Rezept mit Gruppe teilen - public boolean shareRecipeWithGroup(Long groupId, Long recipeId) { - Group group = groupRepository.findById(groupId) - .orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden")); - Recipe recipe = recipeRepository.findById(recipeId) - .orElseThrow(() -> new RuntimeException("Rezept nicht gefunden")); - - GroupRecipe groupRecipe = new GroupRecipe(group, recipe); - groupRecipeRepository.save(groupRecipe); - return true; - } - - // Alle Rezepte einer Gruppe abrufen - public Set getGroupRecipes(Long groupId) { - Group group = groupRepository.findById(groupId) - .orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden")); - return group.getSharedRecipes().stream().map(GroupRecipe::getRecipe).collect(Collectors.toSet()); - } -} diff --git a/src/main/java/com/example/hangry/GroupService.java b/src/main/java/com/example/hangry/GroupService.java deleted file mode 100644 index 2db31cb..0000000 --- a/src/main/java/com/example/hangry/GroupService.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.example.hangry; - -import org.springframework.stereotype.Service; -import java.util.Optional; -import java.util.Set; - -@Service -public class GroupService { - - private final GroupRepository groupRepository; - private final UserRepository userRepository; - - public GroupService(GroupRepository groupRepository, UserRepository userRepository) { - this.groupRepository = groupRepository; - this.userRepository = userRepository; - } - - // Gruppe erstellen - public Group createGroup(String name, String description) { - Group group = new Group(name, description); - return groupRepository.save(group); - } - - // Gruppe beitreten - public boolean joinGroup(Long userId, Long groupId) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User nicht gefunden")); - Group group = groupRepository.findById(groupId) - .orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden")); - - if (!group.getMembers().contains(user)) { - group.getMembers().add(user); - groupRepository.save(group); - return true; - } - return false; - } - - // Gruppe verlassen - public boolean leaveGroup(Long userId, Long groupId) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User nicht gefunden")); - Group group = groupRepository.findById(groupId) - .orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden")); - - if (group.getMembers().contains(user)) { - group.getMembers().remove(user); - groupRepository.save(group); - return true; - } - return false; - } - - // Alle Mitglieder einer Gruppe abrufen - public Set getGroupMembers(Long groupId) { - Group group = groupRepository.findById(groupId) - .orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden")); - return group.getMembers(); - } -} diff --git a/src/main/java/com/example/hangry/IngredientController.java b/src/main/java/com/example/hangry/IngredientController.java deleted file mode 100644 index 82755c1..0000000 --- a/src/main/java/com/example/hangry/IngredientController.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.example.hangry; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import java.util.*; - -@RestController -@RequestMapping("/api/ingredients") -public class IngredientController { - - @Autowired - private IngredientService ingredientService; - - // Globale Zutaten abrufen - @GetMapping("/global") - public List getGlobalIngredients() { - return ingredientService.getGlobalIngredients(); - } - - // Benutzerspezifische Zutaten abrufen - @GetMapping("/user/{userId}") - public List getUserIngredients(@PathVariable Long userId) { - return ingredientService.getUserIngredients(userId); - } - - // Neue globale Zutat hinzufügen - @PostMapping("/global") - public Ingredient addGlobalIngredient(@RequestBody Ingredient ingredient) { - return ingredientService.addGlobalIngredient(ingredient); - } - - // Neue benutzerspezifische Zutat hinzufügen - @PostMapping("/user/{userId}") - public ResponseEntity addUserIngredient(@PathVariable Long userId, @RequestBody Ingredient ingredient) { - try { - Ingredient newIngredient = ingredientService.addUserIngredient(userId, ingredient); - return ResponseEntity.status(HttpStatus.CREATED).body(newIngredient); - } catch (IllegalArgumentException e) { - // Falls die Zutat bereits global existiert - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); - } - } -} diff --git a/src/main/java/com/example/hangry/IngredientService.java b/src/main/java/com/example/hangry/IngredientService.java deleted file mode 100644 index 1773865..0000000 --- a/src/main/java/com/example/hangry/IngredientService.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.example.hangry; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.util.*; - -@Service -public class IngredientService { - - @Autowired - private IngredientRepository ingredientRepository; - - @Autowired - private UserRepository userRepository; - - // Globale Zutaten abrufen - public List getGlobalIngredients() { - return ingredientRepository.findByIsGlobal(true); - } - - // Benutzerspezifische Zutaten abrufen - public List getUserIngredients(Long userId) { - Optional user = userRepository.findById(userId); - if (user.isPresent()) { - return ingredientRepository.findByUserId(userId); - } else { - throw new IllegalArgumentException("User not found with ID: " + userId); - } - } - - // Globale Zutat hinzufügen - public Ingredient addGlobalIngredient(Ingredient ingredient) { - ingredient.setGlobal(true); // Zutat als global markieren - return ingredientRepository.save(ingredient); - } - - // Benutzerdefinierte Zutat hinzufügen, nur wenn sie nicht global existiert - public Ingredient addUserIngredient(Long userId, Ingredient ingredient) { - // Zuerst prüfen, ob diese Zutat bereits global existiert - boolean isGlobalIngredientExists = ingredientRepository.existsByNameAndIsGlobal(ingredient.getName(), true); - - if (isGlobalIngredientExists) { - throw new IllegalArgumentException("Zutat existiert bereits als globale Zutat."); - } - - Optional user = userRepository.findById(userId); - if (user.isPresent()) { - ingredient.setGlobal(false); // Zutat als benutzerspezifisch markieren - ingredient.setUser(user.get()); // Zutat dem Benutzer zuweisen - return ingredientRepository.save(ingredient); - } else { - throw new IllegalArgumentException("User not found with ID: " + userId); - } - } -} diff --git a/src/main/java/com/example/hangry/LikeController.java b/src/main/java/com/example/hangry/LikeController.java deleted file mode 100644 index 291876e..0000000 --- a/src/main/java/com/example/hangry/LikeController.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.example.hangry; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import java.util.List; - -@RestController -@RequestMapping("/api/likes") -@CrossOrigin(origins = "*") -public class LikeController { - - private final LikeService likeService; - - public LikeController(LikeService likeService) { - this.likeService = likeService; - } - - // Rezept liken - @PostMapping("/{userId}/{recipeId}") - public ResponseEntity likeRecipe(@PathVariable Long userId, @PathVariable Long recipeId) { - boolean liked = likeService.likeRecipe(userId, recipeId); - return liked ? ResponseEntity.ok("Rezept geliked") : ResponseEntity.badRequest().body("Bereits geliked"); - } - - // Rezept entliken - @DeleteMapping("/{userId}/{recipeId}") - public ResponseEntity unlikeRecipe(@PathVariable Long userId, @PathVariable Long recipeId) { - boolean unliked = likeService.unlikeRecipe(userId, recipeId); - return unliked ? ResponseEntity.ok("Like entfernt") : ResponseEntity.badRequest().body("Like existiert nicht"); - } - - // Anzahl der Likes für ein Rezept abrufen - @GetMapping("/count/{recipeId}") - public ResponseEntity getLikeCount(@PathVariable Long recipeId) { - return ResponseEntity.ok(likeService.getLikeCount(recipeId)); - } - - // Alle geliketen Rezepte eines Users abrufen - @GetMapping("/user/{userId}") - public ResponseEntity> getLikedRecipes(@PathVariable Long userId) { - return ResponseEntity.ok(likeService.getLikedRecipes(userId)); - } -} - diff --git a/src/main/java/com/example/hangry/LikeService.java b/src/main/java/com/example/hangry/LikeService.java deleted file mode 100644 index 77d7888..0000000 --- a/src/main/java/com/example/hangry/LikeService.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.example.hangry; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.util.List; - -@Service -public class LikeService { - - private final LikeRepository likeRepository; - private final RecipeRepository recipeRepository; - private final UserRepository userRepository; - - public LikeService(LikeRepository likeRepository, RecipeRepository recipeRepository, UserRepository userRepository) { - this.likeRepository = likeRepository; - this.recipeRepository = recipeRepository; - this.userRepository = userRepository; - } - - // Rezept liken - public boolean likeRecipe(Long userId, Long recipeId) { - User user = userRepository.findById(userId).orElseThrow(); - Recipe recipe = recipeRepository.findById(recipeId).orElseThrow(); - - if (likeRepository.existsByUserAndRecipe(user, recipe)) { - return false; // Bereits geliked - } - - Like like = new Like(); - like.setUser(user); - like.setRecipe(recipe); - likeRepository.save(like); - return true; - } - - // Rezept entliken - @Transactional - public boolean unlikeRecipe(Long userId, Long recipeId) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User nicht gefunden")); - Recipe recipe = recipeRepository.findById(recipeId) - .orElseThrow(() -> new RuntimeException("Rezept nicht gefunden")); - - // Prüfen, ob das Like existiert - if (!likeRepository.existsByUserAndRecipe(user, recipe)) { - return false; // Like existiert nicht - } - - likeRepository.deleteByUserAndRecipe(user, recipe); - return true; - } - - - // Anzahl der Likes für ein Rezept abrufen - public long getLikeCount(Long recipeId) { - Recipe recipe = recipeRepository.findById(recipeId).orElseThrow(); - return likeRepository.countByRecipe(recipe); - } - - // Alle geliketen Rezepte eines Users abrufen - public List getLikedRecipes(Long userId) { - User user = userRepository.findById(userId).orElseThrow(); - List likes = likeRepository.findAllByUser(user); - return likes.stream().map(Like::getRecipe).toList(); - } -} diff --git a/src/main/java/com/example/hangry/RecipeController.java b/src/main/java/com/example/hangry/RecipeController.java deleted file mode 100644 index 2c34d30..0000000 --- a/src/main/java/com/example/hangry/RecipeController.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.example.hangry; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import java.util.Optional; - -@RestController -@RequestMapping("/api/recipes") -@CrossOrigin(origins = "*") // Erlaubt CORS für alle Domains, kann angepasst werden -public class RecipeController { - - private final RecipeService recipeService; - - public RecipeController(RecipeService recipeService) { - this.recipeService = recipeService; - } - - // Alle Rezepte mit Pagination abrufen - @GetMapping - public Page getAllRecipes(Pageable pageable) { - return recipeService.getAllRecipes(pageable); - } - - // Einzelnes Rezept nach ID abrufen - @GetMapping("/{id}") - public ResponseEntity getRecipeById(@PathVariable Long id) { - Optional recipe = recipeService.getRecipeById(id); - return recipe.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()); - } - - // Neues Rezept erstellen - @PostMapping - public ResponseEntity createRecipe(@RequestBody Recipe recipe) { - Recipe savedRecipe = recipeService.createRecipe(recipe); - return ResponseEntity.status(HttpStatus.CREATED).body(savedRecipe); - } - - // Rezept aktualisieren - @PutMapping("/{id}") - public ResponseEntity updateRecipe(@PathVariable Long id, @RequestBody Recipe recipe) { - Optional updatedRecipe = recipeService.updateRecipe(id, recipe); - return updatedRecipe.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()); - } - - // Rezept löschen - @DeleteMapping("/{id}") - public ResponseEntity deleteRecipe(@PathVariable Long id) { - if (recipeService.deleteRecipe(id)) { - return ResponseEntity.noContent().build(); - } else { - return ResponseEntity.notFound().build(); - } - } - //Endpunkt: Filter nach Kategorie (z. B. "/api/recipes/filter/category?category=vegan") - @GetMapping("/filter/category") - public Page getRecipesByCategory(@RequestParam String category, Pageable pageable) { - return recipeService.getRecipesByCategory(category, pageable); - } - - // Endpunkt: Filter nach Zutat (z. B. "/api/recipes/filter/ingredient?ingredient=tomate") - @GetMapping("/filter/ingredient") - public Page getRecipesByIngredient(@RequestParam String ingredient, Pageable pageable) { - return recipeService.getRecipesByIngredient(ingredient, pageable); - } -} diff --git a/src/main/java/com/example/hangry/RecipeService.java b/src/main/java/com/example/hangry/RecipeService.java deleted file mode 100644 index e8b2250..0000000 --- a/src/main/java/com/example/hangry/RecipeService.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.example.hangry; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - -import java.util.Optional; - -@Service -public class RecipeService { - - private final RecipeRepository recipeRepository; - - public RecipeService(RecipeRepository recipeRepository) { - this.recipeRepository = recipeRepository; - } - - // Alle Rezepte mit Pagination abrufen - public Page getAllRecipes(Pageable pageable) { - return recipeRepository.findAll(pageable); - } - - // Einzelnes Rezept nach ID abrufen - public Optional getRecipeById(Long id) { - return recipeRepository.findById(id); - } - - // Neues Rezept erstellen - public Recipe createRecipe(Recipe recipe) { - return recipeRepository.save(recipe); - } - - // Rezept aktualisieren - public Optional updateRecipe(Long id, Recipe recipeDetails) { - return recipeRepository.findById(id).map(recipe -> { - if (recipeDetails.getName() != null) recipe.setName(recipeDetails.getName()); - if (recipeDetails.getDescription() != null) recipe.setDescription(recipeDetails.getDescription()); - if (recipeDetails.getCategory() != null) recipe.setCategory(recipeDetails.getCategory()); - if (recipeDetails.getImageUrl() != null) recipe.setImageUrl(recipeDetails.getImageUrl()); - return recipeRepository.save(recipe); - }); - } - - - // Rezept löschen - public boolean deleteRecipe(Long id) { - if (recipeRepository.existsById(id)) { - recipeRepository.deleteById(id); - return true; - } - return false; - } - - //Filter nach Kategorie - public Page getRecipesByCategory(String category, Pageable pageable) { - return recipeRepository.findByCategoryIgnoreCase(category, pageable); - } - - //Filter nach Zutat - public Page getRecipesByIngredient(String ingredient, Pageable pageable) { - return recipeRepository.findByIngredient(ingredient, pageable); - } - -} diff --git a/src/main/java/com/example/hangry/UserController.java b/src/main/java/com/example/hangry/UserController.java deleted file mode 100644 index 5402b4a..0000000 --- a/src/main/java/com/example/hangry/UserController.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.example.hangry; - -import org.springframework.web.bind.annotation.*; -import java.util.List; - -@RestController -@RequestMapping("/users") -public class UserController { - - private final UserService userService; - - public UserController(UserService userService) { - this.userService = userService; - } - - // Endpunkt: Benutzer erstellen - @PostMapping - public User createUser(@RequestBody User user) { - return userService.createUser(user); - } - - // Endpunkt: Benutzer nach Benutzername abrufen - @GetMapping("/username/{username}") - public User getUserByUsername(@PathVariable String username) { - return userService.getUserByUsername(username); - } - - // Endpunkt: Benutzer nach E-Mail abrufen - @GetMapping("/email/{email}") - public User getUserByEmail(@PathVariable String email) { - return userService.getUserByEmail(email); - } -} diff --git a/src/main/java/com/example/hangry/UserService.java b/src/main/java/com/example/hangry/UserService.java deleted file mode 100644 index f81b6c1..0000000 --- a/src/main/java/com/example/hangry/UserService.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.hangry; - -import org.springframework.stereotype.Service; - -@Service -public class UserService { - - private final UserRepository userRepository; - - // Dependency Injection (Spring kümmert sich darum) - public UserService(UserRepository userRepository) { - this.userRepository = userRepository; - } - - // Einen neuen Benutzer erstellen - public User createUser(User user) { - return userRepository.save(user); - } - - // Benutzer anhand des Benutzernamens suchen - public User getUserByUsername(String username) { - return userRepository.findByUsername(username); - } - - // Benutzer anhand der E-Mail suchen - public User getUserByEmail(String email) { - return userRepository.findByEmail(email); - } -} diff --git a/src/main/java/com/example/hangry/security/JwtUtil.java b/src/main/java/com/example/hangry/security/JwtUtil.java new file mode 100644 index 0000000..b001210 --- /dev/null +++ b/src/main/java/com/example/hangry/security/JwtUtil.java @@ -0,0 +1,42 @@ +package com.example.hangry.security; + +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Component; + +import java.security.Key; +import java.util.Date; + +@Component +public class JwtUtil { + private final String SECRET_KEY = "geheimeschluesselgeheimeschluessel"; // Sollte mind. 256 Bit lang sein + private final long EXPIRATION_TIME = 1000 * 60 * 60; // 1 Stunde gültig + + private final Key key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + + //Token generieren + public String generateToken(String username) { + return Jwts.builder() + .setSubject(username) // Benutzername in das Token schreiben + .setIssuedAt(new Date()) // Zeitpunkt der Erstellung + .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // Ablaufzeit setzen + .signWith(key, SignatureAlgorithm.HS256) // Signieren mit geheimer Schlüssel + .compact(); + } + + //Token validieren + public boolean validateToken(String token) { + try { + Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token); + return true; + } catch (JwtException | IllegalArgumentException e) { + return false; + } + } + + //Benutzername aus Token extrahieren + public String extractUsername(String token) { + return Jwts.parserBuilder().setSigningKey(key).build() + .parseClaimsJws(token).getBody().getSubject(); + } +} diff --git a/src/main/java/com/example/hangry/security/SecurityConfig.java b/src/main/java/com/example/hangry/security/SecurityConfig.java new file mode 100644 index 0000000..da458b2 --- /dev/null +++ b/src/main/java/com/example/hangry/security/SecurityConfig.java @@ -0,0 +1,28 @@ +package com.example.hangry.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.config.http.SessionCreationPolicy; + +@Configuration +@EnableWebSecurity // Aktiviert Spring Security +public class SecurityConfig { + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(AbstractHttpConfigurer::disable) // Neue Syntax für CSRF-Disable + .authorizeHttpRequests(auth -> auth + .requestMatchers("/api/auth/register", "/api/auth/login").permitAll() // Registrierung & Login erlauben + .anyRequest().authenticated() // Alles andere erfordert Authentifizierung + ) + .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); // JWT: Keine Session + + return http.build(); + } +} + diff --git a/src/main/java/com/example/hangry/services/JwtService.java b/src/main/java/com/example/hangry/services/JwtService.java new file mode 100644 index 0000000..7ff7189 --- /dev/null +++ b/src/main/java/com/example/hangry/services/JwtService.java @@ -0,0 +1,25 @@ +package com.example.hangry.services; + +import com.example.hangry.User; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Service; +import java.security.Key; +import java.util.Date; + +@Service +public class JwtService { + + private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); + private static final long EXPIRATION_TIME = 1000 * 60 * 60 * 24; // 24 Stunden + + public String generateToken(User user) { + return Jwts.builder() + .setSubject(user.getEmail()) + .setIssuedAt(new Date()) + .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) + .signWith(SECRET_KEY) + .compact(); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index fa43fa2..6367317 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,3 +10,5 @@ spring.jpa.properties.hibernate.use_sql_comments=true spring.jpa.hibernate.ddl-auto=update +server.port=8080 +server.address=0.0.0.0 \ No newline at end of file