Skip to content
Snippets Groups Projects
Commit 87af3239 authored by Abhinav Anurag's avatar Abhinav Anurag
Browse files

Resolve Merge conflicts from sprint 3

parents c3542797 d1957d10
No related branches found
No related tags found
No related merge requests found
Showing
with 552 additions and 73 deletions
......@@ -60,6 +60,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.mockito:mockito-core:4.0.0' // Mocking library
testImplementation 'org.mockito:mockito-junit-jupiter:4.0.0' // JUnit 5 support for Mockito
}
......
package polish_community_group_11.polish_community.news.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import polish_community_group_11.polish_community.news.services.NewsService;
import polish_community_group_11.polish_community.news.models.News;
import polish_community_group_11.polish_community.news.models.NewsImpl;
import java.sql.SQLException;
import java.time.LocalDate;
// controller for the edit news page
// this file is used for handling the displaying the page and for handling the buttons requests
@Controller
public class EditNewsController {
private final NewsService newsService;
@Autowired
public EditNewsController(NewsService newsService) {
this.newsService = newsService;
}
// mapping for the edit page with the particular news id the user is editing
@GetMapping("/editNews/{id}")
public ModelAndView showEditNewsForm(@PathVariable("id") int id) throws SQLException {
// fetch the news by the ID from the news service class
News news = newsService.getNewsById(id);
// error checking
// check to see if the news class is empty
if (news == null) {
throw new IllegalArgumentException("Invalid news ID: " + id);
}
// check to see if the date class is empty and if so then set a default date
if (news.getNews_upload_date() == null) {
news.setNews_upload_date(LocalDate.now());
}
// logs to check if mapping is working correctly
System.out.println("News ID: " + news.getNews_id());
ModelAndView modelAndView = new ModelAndView("news/editNews");
// add the news object to the model
modelAndView.addObject("news", news);
return modelAndView;
}
// post mapping for when the user submits the form
// used @RequestParam due to @ModelAttribute not working
// @RequestParam selects the fields from the form individually
@PostMapping("/editNews/{id}")
public String editOrDeleteNews(@RequestParam("news_id") int news_id,
@RequestParam("news_title") String news_title,
@RequestParam("news_summary") String news_summary,
@RequestParam("news_source") String news_source,
@RequestParam("news_link") String news_link,
@RequestParam("news_image_url") String news_image_url,
@RequestParam("user_id") int user_id,
@RequestParam("news_upload_date") String news_upload_date,
@RequestParam("action") String action) throws SQLException {
// if the user clicks the edit button
if (action.equals("edit")) {
// create new instance of the news class with the data in the fields
News news = new NewsImpl(news_id, news_title, news_summary, news_source, news_link,
news_image_url, user_id, LocalDate.parse(news_upload_date));
// update the news using the news service class
newsService.updateNews(news);
// redirect to the news list
return "redirect:/news";
}
// if the user clicks the delete button
else if (action.equals("delete")) {
// delete the news using the news service class
newsService.deleteNews(news_id);
return "redirect:/news";
}
// error if the event is not recognised
throw new IllegalArgumentException("Invalid action: " + action);
}
}
\ No newline at end of file
......@@ -9,4 +9,11 @@ import java.util.List;
public interface NewsRepository {
public List<News> getAllNews() throws SQLException;
void addNews(News news);}
void addNews(News news);
News getNewsById(int id) throws SQLException;
void updateNews(News news) throws SQLException;
void deleteNews(int id) throws SQLException;
}
......@@ -83,6 +83,7 @@ public class NewsRepositoryImpl implements NewsRepository {
}
}
public void addNews(News news){
String dbInsertSql =
"insert into news " +
......@@ -104,4 +105,65 @@ public class NewsRepositoryImpl implements NewsRepository {
@Override
public News getNewsById(int id) throws SQLException {
String sql = "SELECT * FROM news WHERE news_id = ?";
try {
return jdbc.queryForObject(sql, newsMapper, id);
} catch (EmptyResultDataAccessException e) {
throw new SQLException("No news item found with ID: " + id);
} catch (DataAccessException e) {
throw new SQLException("Error retrieving news with ID: " + id);
}
}
// method for updating news data from the database
@Override
public void updateNews(News news) throws SQLException {
// sql query that says to update the fields where it match the news id
String sql = "UPDATE news SET news_title = ?, news_summary = ?, news_source = ?, news_link = ?, " +
"news_image_url = ?, user_id = ?, news_upload_date = ? WHERE news_id = ?";
try {
// jdbc.update() is a method that will execute the sql query
// replaces the ? with the actual values from the news object
int rowsAffected = jdbc.update(sql,
news.getNews_title(),
news.getNews_summary(),
news.getNews_source(),
news.getNews_link(),
news.getNews_image_url(),
news.getUser_id(),
news.getNews_upload_date(),
news.getNews_id()
);
// error handling
if (rowsAffected == 0) {
throw new SQLException("No news item was updated. Check the ID provided.");
}
} catch (DataAccessException e) {
throw new SQLException("Error updating news with ID: " + news.getNews_id(), e);
}
}
// method for deleting news data from the database
@Override
public void deleteNews(int id) throws SQLException {
// sql query that says to delete the row where the id matches
String sql = "DELETE FROM news WHERE news_id = ?";
try {
// executing the query with the news id
int rowsAffected = jdbc.update(sql, id);
// error handling
if (rowsAffected == 0) {
throw new SQLException("No news item was deleted. Check the ID provided.");
}
} catch (DataAccessException e) {
throw new SQLException("Error deleting news with ID: " + id, e);
}
}
}
......@@ -8,6 +8,13 @@ import java.util.List;
public interface NewsService {
public List<News> getAllNews() throws SQLException;
// Save new news article
void addNews(News news);
News getNewsById(int id) throws SQLException;
void updateNews(News news) throws SQLException;
void deleteNews(int id) throws SQLException;
}
......@@ -22,8 +22,25 @@ public class NewsServiceImpl implements NewsService {
}
@Override
public void addNews(News news) {
newsRepository.addNews(news);
}
public News getNewsById(int id) throws SQLException {
return newsRepository.getNewsById(id);
}
@Override
public void updateNews(News news) throws SQLException {
// link to the repository that directly interactes with the database
newsRepository.updateNews(news);
}
@Override
public void deleteNews(int id) throws SQLException {
newsRepository.deleteNews(id);
}
}
package polish_community_group_11.polish_community.register.controllers;
/*
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.ArrayList;*/
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import polish_community_group_11.polish_community.register.services.UserRepository;
import polish_community_group_11.polish_community.register.models.User;
import polish_community_group_11.polish_community.register.models.Role;
import polish_community_group_11.polish_community.register.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import polish_community_group_11.polish_community.register.services.RoleService;
import java.util.List;
@Controller
public class RegisterController {
......@@ -23,27 +17,39 @@ public class RegisterController {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
// displaying the registration form using get request and ModelAndView
@GetMapping("/register")
public ModelAndView showRegistrationForm() {
// create a ModelAndView object using the register.html file
ModelAndView modelAndView = new ModelAndView("register/register");
// add an empty User object to the model
modelAndView.addObject("user", new User());
// add all the roles currently in the roles table so the so the admin can create a account with a speicif role
modelAndView.addObject("roles", roleService.findAllRoles());
return modelAndView;
}
// for handling form submission
@PostMapping("/register")
public String registerUser(@ModelAttribute User user) {
public String registerUser(@ModelAttribute User user, @RequestParam int roleId) {
if (user.getRole() == null || user.getRole().isEmpty()) {
user.setRole("USER"); // set default role to user
}
// Set the role ID (instead of using the role enum)
user.setRoleId(roleId);
// check to see if the users email already exists
if (userService.findByEmail(user.getEmail()) != null) {
return "redirect:/register?error=email_taken";
}
// save user to the database
userService.saveUser(user);
// redirect to the login page
return "redirect:/login";
}
......
package polish_community_group_11.polish_community.register.dao;
import polish_community_group_11.polish_community.register.models.Role;
import java.util.List;
public interface RoleRepository {
Role findRoleById(int roleId);
List<Role> findAllRoles();
}
\ No newline at end of file
package polish_community_group_11.polish_community.register.dao;
import polish_community_group_11.polish_community.register.models.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Repository;
@Repository
public class RoleRepositoryImpl implements RoleRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
// Fetch a role by its ID
public Role findRoleById(int roleId) {
String sql = "SELECT id, role_name FROM roles WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{roleId}, (rs, rowNum) -> {
Role role = new Role();
role.setId(rs.getInt("id"));
role.setName(rs.getString("role_name"));
return role;
});
}
// Fetch all roles (for displaying in registration form)
public List<Role> findAllRoles() {
String sql = "SELECT id, role_name FROM roles";
return jdbcTemplate.query(sql, (rs, rowNum) -> {
Role role = new Role();
role.setId(rs.getInt("id"));
role.setName(rs.getString("role_name"));
return role;
});
}
}
\ No newline at end of file
package polish_community_group_11.polish_community.register.dao;
import java.util.List;
import polish_community_group_11.polish_community.register.models.User;
public interface UserRepository {
int saveUser(User user); // add user into the database
User findByEmail(String email); // find user by email
User findById(int id); // find user by ID
List<User> findAllUsers(); // get all the users
}
\ No newline at end of file
package polish_community_group_11.polish_community.register.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import polish_community_group_11.polish_community.register.models.User;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.List;
@Repository
public class UserRepositoryImpl implements UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate; // JdbcTemplate is used to interact with the database
// function for saving user
public int saveUser(User user) {
// sql query for inserting into users table
String sql = "INSERT INTO users (email, password, fullname, dob, role_id) VALUES (?, ?, ?, ?, ?)";
int rowsAffected = jdbcTemplate.update(sql,
user.getEmail(),
user.getPassword(),
user.getFullname(),
user.getDateOfBirth(),
user.getRoleId());
if (rowsAffected > 0) {
// if user is successfully inserted, get the user ID
String getUserIdSql = "SELECT LAST_INSERT_ID()";
int userId = jdbcTemplate.queryForObject(getUserIdSql, Integer.class);
// link the user to the role by inserting into the user_roles table
String userRolesSql = "INSERT INTO user_roles (user_id, role_id) VALUES (?, ?)";
jdbcTemplate.update(userRolesSql, userId, user.getRoleId());
return userId; // or return something else if needed
}
return -1;
}
// function for fetching all users
public List<User> findAllUsers() {
// sql query for selecting all users from users table
String sql = "SELECT * FROM users";
return jdbcTemplate.query(sql, (rs, rowNum) -> {
User user = new User();
user.setId(rs.getInt("id"));
user.setEmail(rs.getString("email"));
user.setPassword(rs.getString("password"));
user.setFullname(rs.getString("fullname"));
user.setDateOfBirth(rs.getObject("dob", LocalDate.class)); // attempt to get object by using localdate
user.setRoleId(rs.getInt("role_id"));
return user;
});
}
// function for finding user by email
public User findByEmail(String email) {
// SQL query to find user by email
String sql = "SELECT * FROM users WHERE email = ?";
try {
// Using queryForObject to directly return the result as a single User object
return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> {
User user = new User();
user.setId(rs.getInt("id"));
user.setEmail(rs.getString("email"));
user.setPassword(rs.getString("password"));
user.setFullname(rs.getString("fullname"));
user.setDateOfBirth(rs.getObject("dob", LocalDate.class));
user.setRoleId(rs.getInt("role_id"));
return user;
}, email);
} catch (EmptyResultDataAccessException e) {
// return null if no user is found with the email
return null;
}
}
// function for finding user by id
public User findById(int id) {
// sql query for finding a user by id
String sql = "SELECT * FROM users WHERE id = ?";
try {
// Using queryForObject to directly return the result as a single User object
return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> {
User user = new User();
user.setId(rs.getInt("id"));
user.setEmail(rs.getString("email"));
user.setPassword(rs.getString("password"));
user.setFullname(rs.getString("fullname"));
user.setDateOfBirth(rs.getObject("dob", LocalDate.class));
user.setRoleId(rs.getInt("role_id"));
return user;
}, id);
} catch (EmptyResultDataAccessException e) {
// return null if no user is found with the id
return null;
}
}
}
package polish_community_group_11.polish_community.register.models;
public class Role {
private int id;
private String name; // Role name
// Getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package polish_community_group_11.polish_community.register.models;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.List;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(nullable = false)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String role;
@Column(nullable = false)
private String fullname;
private LocalDate dob; // use LocalDate for dob
private int roleId;
// Getters and setters
// getters and setters
public int getId() {
return id;
}
......@@ -55,11 +44,19 @@ public class User {
this.email = email;
}
public String getRole() {
return role;
public LocalDate getDateOfBirth() {
return dob;
}
public void setDateOfBirth(LocalDate dob) {
this.dob = dob;
}
public int getRoleId() {
return roleId;
}
public void setRole(String role) {
this.role = role;
public void setRoleId(int roleId) {
this.roleId = roleId;
}
}
\ No newline at end of file
package polish_community_group_11.polish_community.register.services;
import polish_community_group_11.polish_community.register.dao.RoleRepository;
import polish_community_group_11.polish_community.register.models.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RoleService {
@Autowired
private RoleRepository roleRepository;
public List<Role> findAllRoles() {
return roleRepository.findAllRoles();
}
public Role findRoleById(int roleId) {
return roleRepository.findRoleById(roleId);
}
}
package polish_community_group_11.polish_community.register.services;
import polish_community_group_11.polish_community.register.models.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
\ No newline at end of file
package polish_community_group_11.polish_community.register.services;
import java.util.List;
import polish_community_group_11.polish_community.register.models.User;
import polish_community_group_11.polish_community.register.services.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public interface UserService {
void saveUser(User user);
@Autowired
private UserRepository userRepository;
User findById(int id);
public User saveUser(User user) {
// uses the Jpa repository built in save methods
return userRepository.save(user);
}
User findByEmail(String email);
public User findById(Long id) {
return userRepository.findById(id).orElse(null);
}
public User findByEmail(String email) {
return userRepository.findByEmail(email);
}
List<User> findAllUsers();
}
\ No newline at end of file
package polish_community_group_11.polish_community.register.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import polish_community_group_11.polish_community.register.models.User;
import polish_community_group_11.polish_community.register.dao.UserRepository;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
// @Autowired has spring automatically create an instance of UserRepository
@Autowired
private UserRepository userRepository;
// @Override marks this method as an implementation of the saveUser method from UserService
@Override
public void saveUser(User user) {
// calls saveUser method
userRepository.saveUser(user);
}
@Override
public User findById(int id) {
// calls findById method
return userRepository.findById(id);
}
@Override
public User findByEmail(String email) {
// calls findByEmail method
return userRepository.findByEmail(email);
}
@Override
public List<User> findAllUsers() {
// Calls findAll method of the UserRepository
return userRepository.findAllUsers();
}
}
......@@ -15,6 +15,8 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import polish_community_group_11.polish_community.register.models.User;
import polish_community_group_11.polish_community.register.services.UserService;
import polish_community_group_11.polish_community.register.models.Role;
import polish_community_group_11.polish_community.register.services.RoleService;
import java.lang.invoke.MethodHandles;
import java.util.Set;
......@@ -26,13 +28,16 @@ public class WebSecurityConfig {
private final UserService userService;
private final RoleService roleService;
private final String[] whiteListingPath = {
// "/event",
// "event/*"
};
public WebSecurityConfig(UserService userService) {
public WebSecurityConfig(UserService userService, RoleService roleService) {
this.userService = userService;
this.roleService = roleService;
}
......@@ -92,9 +97,13 @@ public class WebSecurityConfig {
LOG.error("Couldn't find user with this name: {}", username);
throw new UsernameNotFoundException(username);
}
Role role = roleService.findRoleById(user.getRoleId()); // Assuming getRoleId() returns the roleId
String roleName = "ROLE_" + role.getName().toUpperCase(); // Format the role to ROLE_NAME
//prefix all passwords with {noop} to allow login to run without adding encryption
return new org.springframework.security.core.userdetails.User(user.getEmail(), "{noop}"+user.getPassword(), true, true,
true, true, Set.of(new SimpleGrantedAuthority("ROLE_" + user.getRole())));
true, true, Set.of(new SimpleGrantedAuthority(roleName)));
} catch (DataAccessException e) {
LOG.error("Error when finding user by email: {}", username, e);
throw new UsernameNotFoundException(username);
......
......@@ -162,3 +162,15 @@ insert into event (event_title, event_description, location, event_date, event_t
values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682');
insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url)
values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=');
-- insert standard roles into roles table
INSERT INTO roles (role_name) VALUES ('ADMIN');
INSERT INTO roles (role_name) VALUES ('USER');
-- insert a admin user into the table
insert into users(id, email, password, fullname, dob, role_id)
values(1, "admin@gmail.com", "Password!", "Harri Daives", "2003-07-22", 1);
-- insert the user and role id's of the created roles and user
INSERT INTO user_roles (user_id, role_id)
VALUES (1, 1);
\ No newline at end of file
......@@ -61,3 +61,34 @@ create table if not exists news
user_id int,
news_upload_date date
) engine = InnoDB;
-- drop tables at the start of a session
DROP TABLE IF EXISTS user_roles;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS roles;
-- schema for roles
CREATE TABLE IF NOT EXISTS roles (
id INT AUTO_INCREMENT PRIMARY KEY,
role_name VARCHAR(50) NOT NULL UNIQUE
);
-- schema for users
create table if not exists users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
fullname VARCHAR(255) NOT NULL,
dob DATE,
role_id INT NOT NULL,
FOREIGN KEY (role_id) REFERENCES roles(id)
);
-- schema for user roles
CREATE TABLE IF NOT EXISTS user_roles (
user_id INT,
role_id INT,
PRIMARY KEY (user_id, role_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (role_id) REFERENCES roles(id)
);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment