Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
b4b3e6c
Improved display of recipe creation form
Oksana999 Dec 3, 2020
9765b73
Add edit and delete features
Oksana999 Dec 5, 2020
9d4a4c9
Add edit and delete features
Oksana999 Dec 7, 2020
be1491a
Commented out css
Oksana999 Dec 7, 2020
ba9cde2
Starting to work on saving recipes for users
Oksana999 Dec 7, 2020
a6940e9
Merge pull request #1 from mthreec1983/paalwilliams_removecss
paalwilliams Dec 8, 2020
9f05414
updated password
kellydobbs Dec 8, 2020
7a65a6b
Merge pull request #2 from mthreec1983/kelly_updatedPassword
paalwilliams Dec 8, 2020
a5246b3
Improved display of recipe creation form
Oksana999 Dec 3, 2020
62e7306
login and registration forms
missAH16 Dec 8, 2020
585052e
Merge pull request #3 from mthreec1983/oksana-save-user-recipe
mthreec1983 Dec 10, 2020
19078c3
Merge branch 'master' into Athena_login_registration_form
missAH16 Dec 10, 2020
826ac70
corrected_forms
missAH16 Dec 10, 2020
0c95069
Merge pull request #5 from mthreec1983/Athena_login_registreation_form
mthreec1983 Dec 10, 2020
f799652
initial commit
kellydobbs Dec 14, 2020
6e15c51
calc avg and display
kellydobbs Dec 14, 2020
ab2b888
display comments and total reviews
kellydobbs Dec 14, 2020
37108f4
Change language
Oksana999 Dec 14, 2020
7828909
Merge branches 'master' and 'oksana-save-user-recipe' of https://gith…
Oksana999 Dec 14, 2020
b1bdb9a
Add possibility to save favorite recipes
Oksana999 Dec 14, 2020
5842391
Added search feature, need to improve
Dec 14, 2020
512fbe9
updated average calculation
kellydobbs Dec 14, 2020
a7395ea
Merge pull request #6 from mthreec1983/oksana-save-user-recipe
kellydobbs Dec 15, 2020
98688f8
Merge remote-tracking branch 'origin/master' into kelly-review-new
kellydobbs Dec 15, 2020
3de6f6c
merged master
kellydobbs Dec 16, 2020
1e0928a
added timestamp and name field
kellydobbs Dec 17, 2020
c286ab3
add /search to whitelist
paalwilliams Dec 18, 2020
e1f7202
Merge pull request #7 from mthreec1983/Reyna/Search
paalwilliams Dec 18, 2020
5601b63
Add header-navigation
Oksana999 Dec 21, 2020
8e48a47
uncommited changes
kellydobbs Dec 22, 2020
c800a9f
trying to do search by category
Dec 22, 2020
47c1aae
finished search by category
Dec 22, 2020
2f7ed52
disable adding the same recipe to user profile
Oksana999 Dec 22, 2020
c1df5b5
revised search by keyword to include searching in ingredients,directi…
Dec 22, 2020
5cc9393
Merge pull request #8 from mthreec1983/Oksana-header-navigation
paalwilliams Jan 2, 2021
1d5e069
ongoing sort feature
Jan 2, 2021
744c9ae
display only reviews with comments
kellydobbs Jan 3, 2021
728000c
added form validation
kellydobbs Jan 3, 2021
4e288ca
added responsive front-end rating
kellydobbs Jan 3, 2021
5b63854
front-end responsive rating
kellydobbs Jan 3, 2021
c3ee261
Merge remote-tracking branch 'origin/master' into kelly-review-new
kellydobbs Jan 3, 2021
6810060
added oksana's changes
kellydobbs Jan 3, 2021
2ab1693
added more of Oksana's edits
kellydobbs Jan 3, 2021
17fd263
added display.html to whitelist
kellydobbs Jan 3, 2021
5e8dad8
refactored
kellydobbs Jan 3, 2021
18eb03b
continuation of sort feature
Jan 3, 2021
2243b12
finished SORT feature
Jan 3, 2021
b9b971a
Merge remote-tracking branch 'origin/kelly-review-new' into Reyna/Sea…
Jan 3, 2021
e3cbecd
Merge pull request #9 from mthreec1983/kelly-review-new
reynabiyo20 Jan 4, 2021
48f0006
Merge remote-tracking branch 'origin/master' into Reyna/Search-filter
Jan 4, 2021
96e8658
added sort by rating
Jan 4, 2021
cf1df3b
started filter search result feature
Jan 5, 2021
c6a19a6
added sort by category in /home and /recipe/display. Filter feature i…
Jan 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.security:spring-security-crypto'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
Expand Down
158 changes: 158 additions & 0 deletions recipes_table_and_data.sql

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions src/main/java/org/launchcode/recipeapp/AuthenticationFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.launchcode.recipeapp;



import org.launchcode.recipeapp.controllers.AuthenticationController;
import org.launchcode.recipeapp.models.User;
import org.launchcode.recipeapp.models.data.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class AuthenticationFilter extends HandlerInterceptorAdapter {

@Autowired
UserRepository userRepository;

@Autowired
AuthenticationController authenticationController;

private static final List<String> whitelist = Arrays.asList("/home", "/login", "/register", "/logout", "/css", "/recipes/all", "/recipes/display", "/search");

private static boolean isWhitelisted(String path) {
for (String pathRoot : whitelist) {
if (path.startsWith(pathRoot)) {
return true;
}
}
return false;
}

@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws IOException {

if (isWhitelisted(request.getRequestURI())) {
return true;

}

HttpSession session = request.getSession();
User user = authenticationController.getUserFromSession(session);

// The user is logged in
if (user != null) {
return true;
}

// The user is NOT logged in
response.sendRedirect("/home");
return false;
}
}
20 changes: 20 additions & 0 deletions src/main/java/org/launchcode/recipeapp/WebApplicationConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.launchcode.recipeapp;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebApplicationConfig implements WebMvcConfigurer {

@Bean
public AuthenticationFilter authenticationFilter() {
return new AuthenticationFilter();
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationFilter());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package org.launchcode.recipeapp.controllers;

import org.launchcode.recipeapp.models.Category;
import org.launchcode.recipeapp.models.data.UserRepository;
import org.launchcode.recipeapp.models.dto.LoginFormDTO;
import org.launchcode.recipeapp.models.User;
import org.launchcode.recipeapp.models.dto.RegistrationFormDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.Optional;

@Controller
public class
AuthenticationController {

@Autowired
UserRepository userRepository;

private static final String userSessionKey = "user";

public User getUserFromSession(HttpSession session) {
return (User) session.getAttribute(userSessionKey);
}

private static void setUserInSession(HttpSession session, User user) {
session.setAttribute(userSessionKey, user);
}

@GetMapping("/register")
public String displayRegistrationForm(Model model) {
model.addAttribute(new RegistrationFormDTO());
model.addAttribute("title", "Register");
return "register";
}

@PostMapping("/register")
public String processRegistrationForm(@ModelAttribute @Valid RegistrationFormDTO registrationFormDTO,
Errors errors, HttpServletRequest request,
Model model) {

if (errors.hasErrors()) {
model.addAttribute("title", "Register");
return "register";
}

User existingUser = userRepository.findByUsername(registrationFormDTO.getUsername());

if (existingUser != null) {
errors.rejectValue("username", "username.already exists", "A user with that username already exists");
model.addAttribute("title", "Register");
return "register";
}

String password = registrationFormDTO.getPassword();
String verifyPassword = registrationFormDTO.getVerifyPassword();
if (!password.equals(verifyPassword)) {
errors.rejectValue("password", "passwords.mismatch", "Passwords do not match");
model.addAttribute("title", "Register");
return "register";
}

User newUser = new User(registrationFormDTO.getUsername(), registrationFormDTO.getPassword());
userRepository.save(newUser);
setUserInSession(request.getSession(), newUser);

return "redirect:/home";
}

@GetMapping("/login")
public String displayLoginForm(Model model) {
model.addAttribute(new LoginFormDTO());
model.addAttribute("title", "Log In");
model.addAttribute("categories", Category.values());
return "login";
}

@PostMapping("/login")
public String processLoginForm(@ModelAttribute @Valid LoginFormDTO loginFormDTO,
Errors errors, HttpServletRequest request,
Model model) {

if (errors.hasErrors()) {
model.addAttribute("title", "Log In");
return "login";
}


User theUser = userRepository.findByUsername(loginFormDTO.getUsername());

if (theUser == null) {
errors.rejectValue("username", "user.invalid", "The given username does not exist");
model.addAttribute("title", "Log In");
return "login";
}

String password = loginFormDTO.getPassword();

if (!theUser.isMatchingPassword(password)) {
errors.rejectValue("password", "password.invalid", "Invalid password");
model.addAttribute("title", "Log In");
return "login";
}

setUserInSession(request.getSession(), theUser);

return "redirect:/home";
}


@GetMapping("/logout")
public String logout(HttpServletRequest request){
request.getSession().invalidate();
return "redirect:/login";
}

}
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package org.launchcode.recipeapp.controllers;


import org.launchcode.recipeapp.data.RecipeRepository;
import org.launchcode.recipeapp.models.Category;
import org.launchcode.recipeapp.models.Recipe;
import org.launchcode.recipeapp.models.data.RecipeRepository;
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 java.util.ArrayList;
import java.util.List;

/**
* @author Oksana
*/
Expand All @@ -24,15 +22,12 @@ public HomeController(RecipeRepository recipeRepository) {
this.recipeRepository = recipeRepository;
}

@GetMapping("")
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("title", "Saint Louis Best Recipes");

List<Recipe> recipes = new ArrayList<>();
Iterable<Recipe> all = recipeRepository.findAll();
all.forEach(recipes::add);

model.addAttribute("recipes", recipes);
model.addAttribute("categories", Category.values());
model.addAttribute("recipes", all);
model.addAttribute("title", "Saint Louis Best Recipes");

return "index";
}
Expand Down
Loading