Update 16 files

- /src/main/resources/templates/create-account.html
- /src/main/resources/templates/my-profile.html
- /src/main/resources/templates/home.html
- /src/main/resources/templates/update-recipe.html
- /src/main/resources/templates/explore.html
- /src/main/resources/templates/public-profile.html
- /src/main/java/com/example/demo/controller/SiteController.java
- /src/main/java/com/example/demo/controller/ProfileController.java
- /src/main/java/com/example/demo/dto/UserDto.java
- /src/main/java/com/example/demo/dto/UpdateProfileDto.java
- /src/main/java/com/example/demo/dto/ProfileDto.java
- /src/main/java/com/example/demo/service/Impl/RecipeServiceImpl.java
- /src/main/java/com/example/demo/service/Impl/UserServiceImpl.java
- /src/main/java/com/example/demo/service/UserService.java
- /src/main/java/com/example/demo/config/SecurityConfig.java
- /src/main/java/com/example/demo/entity/User.java
This commit is contained in:
Madeleine Stamp
2026-04-18 14:08:08 -06:00
parent c2e6722829
commit 659ab79497
16 changed files with 781 additions and 292 deletions
@@ -1,4 +1,4 @@
package com.example.demo.config;
ppackage com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -6,7 +6,6 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.csrf.CsrfAuthenticationStrategy;
@Configuration
public class SecurityConfig {
@@ -22,6 +21,7 @@ public class SecurityConfig {
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/register", "/css/**", "/images/**").permitAll()
.requestMatchers("/api/users").permitAll()
.requestMatchers("/users/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
@@ -0,0 +1,54 @@
package com.example.demo.controller;
import java.security.Principal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import com.example.demo.dto.ProfileDto;
import com.example.demo.dto.UpdateProfileDto;
import com.example.demo.service.UserService;
@Controller
public class ProfileController {
private final UserService userService;
public ProfileController(UserService userService) {
this.userService = userService;
}
@GetMapping("/users/{id}")
public String viewPublicProfile(@PathVariable Integer id, Model model) {
ProfileDto profile = userService.getProfileByUserId(id);
model.addAttribute("profile", profile);
return "public-profile";
}
@GetMapping("/my-profile")
public String viewMyProfile(Principal principal, Model model) {
String username = principal.getName();
ProfileDto profile = userService.getCurrentUserProfile(username);
UpdateProfileDto updateProfileDto = new UpdateProfileDto();
updateProfileDto.setDisplayName(profile.getDisplayName());
updateProfileDto.setBio(profile.getBio());
model.addAttribute("profile", profile);
model.addAttribute("updateProfileDto", updateProfileDto);
return "my-profile";
}
@PostMapping("/my-profile/update")
public String updateMyProfile(@ModelAttribute UpdateProfileDto dto, Principal principal) {
String username = principal.getName();
userService.updateProfile(username, dto);
return "redirect:/my-profile";
}
}
@@ -2,10 +2,8 @@ package com.example.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.example.demo.service.RecipeService;
import com.example.demo.dto.RecipeDto;
import com.example.demo.entity.Recipe;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@@ -20,10 +18,10 @@ public class SiteController {
public SiteController(RecipeService recipeService) {
this.recipeService = recipeService;
}
@GetMapping("/")
public String viewHomePage(Model model) {
//model.addAttribute("allemplist", employeeServiceImpl.getAllEmployee());
List<RecipeDto> recipes = recipeService.getAllRecipes();
List<RecipeDto> recipes = recipeService.getAllRecipes();
model.addAttribute("recipes", recipes);
return "home";
}
@@ -49,14 +47,13 @@ public class SiteController {
model.addAttribute("recipe", recipe);
return "view-recipe";
}
// @GetMapping("/explore")
// public String viewExplorePage(Model model) {
// //model.addAttribute("allemplist", employeeServiceImpl.getAllEmployee());
// List<RecipeDto> recipes = recipeService.getAllRecipes();
// model.addAttribute("recipes", recipes);
// return "explore";
// }
@GetMapping("/recipes/{id}/edit")
public String viewEditRecipePage(@PathVariable Integer id, Model model) {
RecipeDto recipe = recipeService.getRecipeById(id);
model.addAttribute("recipe", recipe);
return "update-recipe";
}
@GetMapping("/explore")
public String explore(
@@ -69,13 +66,8 @@ public class SiteController {
) {
List<RecipeDto> recipes = recipeService.getRecipes(q, tags, prices, cookTime, prepTime);
model.addAttribute("recipes", recipes);
String displayQuery = q;
model.addAttribute("q", q);
model.addAttribute("tags", tags);
return "explore";
}
}
@@ -0,0 +1,61 @@
package com.example.demo.dto;
import java.util.List;
public class ProfileDto {
private Integer id;
private String username;
private String displayName;
private String bio;
private List<RecipeDto> recipes;
public ProfileDto() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public List<RecipeDto> getRecipes() {
return recipes;
}
public void setRecipes(List<RecipeDto> recipes) {
this.recipes = recipes;
}
public String getEffectiveDisplayName() {
if (displayName != null && !displayName.isBlank()) {
return displayName;
}
return username;
}
}
@@ -0,0 +1,25 @@
package com.example.demo.dto;
public class UpdateProfileDto {
private String displayName;
private String bio;
public UpdateProfileDto() {
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
}
@@ -4,6 +4,8 @@ public class UserDto {
private Integer id;
private String username;
private String email;
private String displayName;
private String bio;
public UserDto() {
}
@@ -14,6 +16,14 @@ public class UserDto {
this.email = email;
}
public UserDto(Integer id, String username, String email, String displayName, String bio) {
this.id = id;
this.username = username;
this.email = email;
this.displayName = displayName;
this.bio = bio;
}
public Integer getId() {
return id;
}
@@ -38,4 +48,26 @@ public class UserDto {
this.email = email;
}
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public String getEffectiveDisplayName() {
if (displayName != null && !displayName.isBlank()) {
return displayName;
}
return username;
}
}
@@ -34,6 +34,12 @@ public class User implements UserDetails {
@Column(nullable = false, unique = true)
private String username;
@Column(length = 100)
private String displayName;
@Column(length = 1000)
private String bio;
@Column(nullable = false)
private String role;
@@ -118,6 +124,22 @@ public class User implements UserDetails {
this.username = username;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public String getRole() {
return role;
}
@@ -173,4 +195,11 @@ public class User implements UserDetails {
public void setFavRecipes(Set<Recipe> favRecipes) {
this.FavRecipes = favRecipes;
}
public String getEffectiveDisplayName() {
if (displayName != null && !displayName.isBlank()) {
return displayName;
}
return username;
}
}
@@ -71,8 +71,13 @@ public class RecipeServiceImpl implements RecipeService {
List<TagDto> tagDtos = recipe.getTags().stream().map(ri -> new TagDto(ri.getName())).toList();
UserDto userDto = new UserDto(recipe.getUser().getId(), recipe.getUser().getUsername(),
recipe.getUser().getEmail());
UserDto userDto = new UserDto(
recipe.getUser().getId(),
recipe.getUser().getUsername(),
recipe.getUser().getEmail(),
recipe.getUser().getDisplayName(),
recipe.getUser().getBio()
);
RecipeDto dto = new RecipeDto(recipe.getTitle(), recipe.getDescription(), recipe.getPrepTimeMinutes(),
recipe.getCookTimeMinutes(), recipe.getServings(), userDto, recipe.getStatus(), ingredientDtos,
@@ -129,7 +134,6 @@ public class RecipeServiceImpl implements RecipeService {
ensureUserNotBanned(currentUser);
enforceUploadLimit(currentUser);
Recipe recipe = new Recipe(dto.getTitle(), dto.getDescription(), dto.getPrepTimeMinutes(),
dto.getCookTimeMinutes(), dto.getServings(), currentUser, dto.getStatus(), dto.getCost());
@@ -375,7 +379,7 @@ public class RecipeServiceImpl implements RecipeService {
public List<RecipeDto> getRecipes(String name, List<String> tags, List<Integer> prices, List<Integer> cookTime, List<Integer> prepTime) {
List<Recipe> recipes;
if ((name != null) && (!name.isBlank())) {
recipes = recipeRepository.findByTitleContainingIgnoreCase(name);
}
@@ -389,13 +393,13 @@ public class RecipeServiceImpl implements RecipeService {
.filter(recipe -> recipe.getTags().stream().anyMatch(tag -> tags.contains(tag.getName())))
.collect(Collectors.toList());
}
if (prices != null && !prices.isEmpty() && !recipes.isEmpty()) {
recipes = recipes.stream()
.filter(recipe -> prices.contains(recipe.getCost()))
.collect(Collectors.toList());
}
if (cookTime != null && !cookTime.isEmpty() && !recipes.isEmpty()) {
recipes = recipes.stream()
.filter(recipe -> {
@@ -411,7 +415,7 @@ public class RecipeServiceImpl implements RecipeService {
})
.collect(Collectors.toList());
}
if (prepTime != null && !prepTime.isEmpty() && !recipes.isEmpty()) {
recipes = recipes.stream()
.filter(recipe -> {
@@ -428,7 +432,6 @@ public class RecipeServiceImpl implements RecipeService {
.collect(Collectors.toList());
}
List<RecipeDto> recipeList = new ArrayList<>();
for (Recipe recipe : recipes) {
@@ -2,24 +2,20 @@ package com.example.demo.service.Impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.example.demo.dto.ImageDto;
import com.example.demo.dto.RecipeDto;
import com.example.demo.dto.RecipeIngredientDto;
import com.example.demo.dto.StepDto;
import com.example.demo.dto.TagDto;
import com.example.demo.dto.ProfileDto;
import com.example.demo.dto.UpdateProfileDto;
import com.example.demo.dto.UserDto;
import com.example.demo.dto.RecipeDto;
import com.example.demo.entity.Recipe;
import com.example.demo.entity.User;
import com.example.demo.exception.NotFoundException;
import com.example.demo.repository.RecipeRepo;
import com.example.demo.repository.UserRepo;
import com.example.demo.service.RecipeService;
import com.example.demo.service.UserService;
import jakarta.transaction.Transactional;
@@ -30,16 +26,26 @@ public class UserServiceImpl implements UserService {
private UserRepo userRepository;
private RecipeRepo recipeRepository;
private PasswordEncoder passwordEncoder;
private RecipeService recipeService;
public UserServiceImpl(UserRepo userRepository, RecipeRepo recipeRepository, PasswordEncoder passwordEncoder) {
public UserServiceImpl(UserRepo userRepository, RecipeRepo recipeRepository,
PasswordEncoder passwordEncoder, RecipeService recipeService) {
super();
this.userRepository = userRepository;
this.recipeRepository = recipeRepository;
this.passwordEncoder = passwordEncoder;
this.recipeService = recipeService;
}
@Override
public UserDto convertToDto(User user) {
return new UserDto(user.getId(), user.getUsername(), user.getEmail());
return new UserDto(
user.getId(),
user.getUsername(),
user.getEmail(),
user.getDisplayName(),
user.getBio()
);
}
@Override
@@ -49,27 +55,23 @@ public class UserServiceImpl implements UserService {
}
user.setBanned(false);
user.setHashedpassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
@Override
public List<UserDto> getAllUsers() {
List<UserDto> list = new ArrayList<>();
for (User user : userRepository.findAll()) {
UserDto userDto = convertToDto(user);
list.add(userDto);
}
return list;
}
@Override
public UserDto getUserById(Integer Id) {
return convertToDto(userRepository.findById(Id).orElseThrow(() -> new NotFoundException("User", "id", Id)));
public UserDto getUserById(Integer id) {
return convertToDto(userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User", "id", id)));
}
@Override
@@ -88,9 +90,9 @@ public class UserServiceImpl implements UserService {
}
@Override
public UserDto updateUser(User user, Integer Id) {
User existingUser = userRepository.findById(Id).orElseThrow(() -> new NotFoundException("User", "id", Id));
public UserDto updateUser(User user, Integer id) {
User existingUser = userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User", "id", id));
existingUser.setUsername(user.getUsername());
existingUser.setEmail(user.getEmail());
@@ -101,9 +103,10 @@ public class UserServiceImpl implements UserService {
}
@Override
public void deleteUser(Integer Id) {
userRepository.findById(Id).orElseThrow(() -> new NotFoundException("User", "id", Id));
userRepository.deleteById(Id);
public void deleteUser(Integer id) {
userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User", "id", id));
userRepository.deleteById(id);
}
@Override
@@ -114,27 +117,26 @@ public class UserServiceImpl implements UserService {
Recipe existingRecipe = recipeRepository.findById(recipeId)
.orElseThrow(() -> new NotFoundException("Recipe", "id", recipeId));
userRepository.save(existingUser);
existingUser.getFavRecipes().remove(existingRecipe);
userRepository.save(existingUser);
}
@Override
public List<UserDto> getUsersByName(String name) {
List<User> users = userRepository.findByUsernameContainingIgnoreCase(name);
if (users.isEmpty()) {
throw new NotFoundException("User", "username containing", name);
}
if (users.isEmpty()) {
throw new NotFoundException("User", "username containing", name);
}
List<UserDto> userList = new ArrayList<>();
List<UserDto> userList = new ArrayList<>();
for (User user : users) {
UserDto dto = convertToDto(user);
userList.add(dto);
}
return userList;
for (User user : users) {
UserDto dto = convertToDto(user);
userList.add(dto);
}
return userList;
}
@Override
@@ -172,4 +174,50 @@ public class UserServiceImpl implements UserService {
userRepository.save(user);
return convertToDto(user);
}
}
@Override
@Transactional
public ProfileDto getProfileByUserId(Integer userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new NotFoundException("User", "id", userId));
List<Recipe> recipes = recipeRepository.findByUserId(userId);
List<RecipeDto> recipeDtos = new ArrayList<>();
for (Recipe recipe : recipes) {
recipeDtos.add(recipeService.convertToDto(recipe));
}
ProfileDto profile = new ProfileDto();
profile.setId(user.getId());
profile.setUsername(user.getUsername());
profile.setDisplayName(user.getDisplayName());
profile.setBio(user.getBio());
profile.setRecipes(recipeDtos);
return profile;
}
@Override
@Transactional
public ProfileDto getCurrentUserProfile(String username) {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new NotFoundException("User", "username", username));
return getProfileByUserId(user.getId());
}
@Override
@Transactional
public ProfileDto updateProfile(String username, UpdateProfileDto dto) {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new NotFoundException("User", "username", username));
user.setDisplayName(dto.getDisplayName());
user.setBio(dto.getBio());
userRepository.save(user);
return getProfileByUserId(user.getId());
}
}
@@ -2,6 +2,8 @@ package com.example.demo.service;
import java.util.List;
import com.example.demo.dto.ProfileDto;
import com.example.demo.dto.UpdateProfileDto;
import com.example.demo.dto.UserDto;
import com.example.demo.entity.User;
@@ -31,4 +33,10 @@ public interface UserService {
UserDto makeAdmin(Integer id);
UserDto makeUser(Integer id);
ProfileDto getProfileByUserId(Integer userId);
ProfileDto getCurrentUserProfile(String username);
ProfileDto updateProfile(String username, UpdateProfileDto dto);
}