diff --git a/MySQL_conf_pbx/test1/mariadb_data/aria_log.00000001 b/MySQL_conf_pbx/test1/mariadb_data/aria_log.00000001 index 11fe1d3..03dc234 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/aria_log.00000001 and b/MySQL_conf_pbx/test1/mariadb_data/aria_log.00000001 differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/aria_log_control b/MySQL_conf_pbx/test1/mariadb_data/aria_log_control index d4b3e74..0c8bf2c 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/aria_log_control and b/MySQL_conf_pbx/test1/mariadb_data/aria_log_control differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/roles.ibd b/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/roles.ibd index 8e7d863..b92c3ff 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/roles.ibd and b/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/roles.ibd differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user.ibd b/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user.ibd index 95d8e61..6822d21 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user.ibd and b/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user.ibd differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user_roles.ibd b/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user_roles.ibd index 8d181c2..50b6857 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user_roles.ibd and b/MySQL_conf_pbx/test1/mariadb_data/asterisk_db/user_roles.ibd differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/ib_buffer_pool b/MySQL_conf_pbx/test1/mariadb_data/ib_buffer_pool index 7603c98..919030e 100644 --- a/MySQL_conf_pbx/test1/mariadb_data/ib_buffer_pool +++ b/MySQL_conf_pbx/test1/mariadb_data/ib_buffer_pool @@ -9,11 +9,6 @@ 18,2 18,1 18,0 -16,4 -16,3 -16,2 -16,1 -16,0 14,4 14,3 14,2 @@ -166,20 +161,18 @@ 3,10 2,10 1,10 +3,49 3,9 2,9 1,9 3,8 2,8 1,8 -3,49 3,7 2,7 1,7 3,6 -2,46 2,6 -1,50 1,6 3,5 2,5 diff --git a/MySQL_conf_pbx/test1/mariadb_data/ib_logfile0 b/MySQL_conf_pbx/test1/mariadb_data/ib_logfile0 index e129207..db57855 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/ib_logfile0 and b/MySQL_conf_pbx/test1/mariadb_data/ib_logfile0 differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/ibdata1 b/MySQL_conf_pbx/test1/mariadb_data/ibdata1 index 1fa06ce..c4dc296 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/ibdata1 and b/MySQL_conf_pbx/test1/mariadb_data/ibdata1 differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/undo001 b/MySQL_conf_pbx/test1/mariadb_data/undo001 index 63a9ad2..cdac51b 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/undo001 and b/MySQL_conf_pbx/test1/mariadb_data/undo001 differ diff --git a/MySQL_conf_pbx/test1/mariadb_data/undo002 b/MySQL_conf_pbx/test1/mariadb_data/undo002 index 7ff929e..1ac9977 100644 Binary files a/MySQL_conf_pbx/test1/mariadb_data/undo002 and b/MySQL_conf_pbx/test1/mariadb_data/undo002 differ diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAO.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAO.java index e26c928..f998341 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAO.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAO.java @@ -12,5 +12,7 @@ public interface UserOpsDAO { public boolean checkIfAdminExists(UserEntity userEntity) throws Exception; // admin login - public ReturnStatus adminSetPasswordToDb(UserEntity userEntity); + public ReturnStatus adminSetUsernameAndPassword(UserEntity userEntity); + + public UserEntity getUserByUserName(String userName); } diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAOImpl.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAOImpl.java index 0e47754..675f9f5 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAOImpl.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DAO/UserOpsDAOImpl.java @@ -5,6 +5,7 @@ import com.example.cezenPBX.entity.user.Role; import com.example.cezenPBX.entity.user.UserEntity; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; +import jakarta.persistence.TypedQuery; import jakarta.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -32,18 +33,19 @@ public class UserOpsDAOImpl implements UserOpsDAO{ // Admin sets a username and password for the first time @Override @Transactional - public ReturnStatus adminSetPasswordToDb(UserEntity userEntity) { + public ReturnStatus adminSetUsernameAndPassword(UserEntity userEntity) { try { if (checkIfAdminExists(userEntity)) { return new ReturnStatus(false, "Admin already exists", ""); } // Fetch existing ROLE_Admin from DB - Role adminRole = (Role) entityManager.createQuery("FROM Role r WHERE r.role = :roleName") - .setParameter("roleName", "ROLE_Admin") - .getSingleResult(); + TypedQuery query = entityManager.createQuery("FROM Role r WHERE r.role = :roleName", Role.class) + .setParameter("roleName", "ROLE_Admin"); - userEntity.setARole(adminRole); + Role role = query.getSingleResult(); + + userEntity.setARole(role); // Persist the user entityManager.persist(userEntity); return new ReturnStatus(true, "Admin created", ""); @@ -51,4 +53,23 @@ public class UserOpsDAOImpl implements UserOpsDAO{ return new ReturnStatus(false, "Admin creation failed", e.getMessage()); } } + + // get user details by username + // throws an exception if the user doesn't exist + // exception is caught and returns null ... custom authentication provider must catch the exception + @Override + public UserEntity getUserByUserName(String userName) { + + try{ + TypedQuery query = this.entityManager + .createQuery("SELECT u FROM UserEntity u JOIN FETCH u.roles AS r WHERE u.userName = :userName", UserEntity.class); + + query.setParameter("userName", userName); + + return query.getSingleResult(); + + }catch ( Exception e){ + return null; + } + } } diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DTO/user/AdminSetPasswordDTO.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DTO/user/AdminSetPasswordDTO.java index b2f2002..a850c8f 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DTO/user/AdminSetPasswordDTO.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/DTO/user/AdminSetPasswordDTO.java @@ -12,7 +12,7 @@ public record AdminSetPasswordDTO( String email, @NotBlank(message = "Password cannot be blank") - @Size(min = 8, message = "Password must be at least 8 characters long") + @Size(min = 3, message = "Password must be at least 8 characters long") String password, @NotBlank(message = "Confirm password cannot be blank") diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CezenLoginSecurityChain.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CezenLoginSecurityChain.java index aa35a37..191651c 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CezenLoginSecurityChain.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CezenLoginSecurityChain.java @@ -6,7 +6,6 @@ import com.example.cezenPBX.security.JWTTokenValidatorFilter; import jakarta.servlet.http.HttpServletRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; @@ -80,16 +79,17 @@ public class CezenLoginSecurityChain { "/admin/list_all_branches_with_manager" ).hasAnyRole("admin") //any one who is authenticated can access /logout - .requestMatchers("/bankUser/login", "/user/getXSRfToken", "/logout").authenticated() + .requestMatchers("/open/login", "/user/getXSRfToken", "/logout").authenticated() .requestMatchers("/bankUser/**").hasAnyRole("user") //all the rest are open to public - .requestMatchers("/open/**").permitAll() + .requestMatchers("/open/signup").permitAll() //.requestMatchers(HttpMethod.POST, "/open/**").permitAll() ) // redirect to /login if the user is not authenticated Customizer.withDefaults() enables a security feature using the defaults provided by Spring Security .formLogin(Customizer.withDefaults()) .httpBasic(Customizer.withDefaults()); + System.out.print("Security chain configured"); return http.build(); } diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CustomAuthenticationProviderForCezen.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CustomAuthenticationProviderForCezen.java index 3eb2a41..b6c7677 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CustomAuthenticationProviderForCezen.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/config/CustomAuthenticationProviderForCezen.java @@ -1,146 +1,81 @@ -//package com.example.cezenPBX.config; -// -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.security.authentication.AuthenticationProvider; -//import org.springframework.security.authentication.BadCredentialsException; -//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -//import org.springframework.security.core.Authentication; -//import org.springframework.security.core.AuthenticationException; -//import org.springframework.security.core.GrantedAuthority; -//import org.springframework.security.core.authority.SimpleGrantedAuthority; -//import org.springframework.security.crypto.password.PasswordEncoder; -// -//import java.util.ArrayList; -//import java.util.List; -// -//public class CustomAuthenticationProviderForCezen implements AuthenticationProvider { -// -// @Autowired -// private UserRepository userRepository; -// -// @Autowired -// private EmployeeRepository employeeRepository; -// -// @Autowired -// private PasswordEncoder passwordEncoder; -// -// @Override -// public Authentication authenticate(Authentication authentication) throws AuthenticationException { -// -// //get credentials from login form -// String username = authentication.getName(); -// String pwd = authentication.getCredentials().toString(); -// -// //sanity check -// if (username.isEmpty() || pwd.isEmpty()) return null; -// -// System.out.println(pwd); -// System.out.println(username); -// -// int employeeId = 0; -// boolean isEmployee = false; -// -// //what if the username is an employee login -// try { -// //if true -// employeeId = Integer.parseInt(username); -// isEmployee = true; -// } catch (Exception e) { -// System.out.println(e.toString()); -// } -// -// //employee auth -// if (isEmployee) { -// // if it is a valid number range -// if (employeeId > 0) { -// //check for employee -// Employee employee = null; -// try { -// //check if employee exists if yes then fetch details -// employee = employeeRepository.getEmployeeAndRolesById(employeeId); -// } catch (Exception e) { -// System.out.println(e.toString()); -// return null; -// } -// -// if (passwordEncoder.matches(pwd, employee.getPassword())) { -// -// //then it is a match a number of springs granted authorities -// List authorities = new ArrayList<>(); -// -// //loop through the users authorities and add each of them to simple granted authority -// try { -// -// //check if employee is part of permission set for employee signing in -// boolean hasEmployee = false; -// for(var permission : employee.getRoles()){ -// if(permission.getRole().equals("ROLE_employee")) hasEmployee = true; -// } -// if(!hasEmployee) throw new BadCredentialsException("no employee permission for given employee"); -// -// employee.getRoles().forEach(a -> authorities.add(new SimpleGrantedAuthority(a.getRole()))); -// } catch (Exception e) { -// //use/**/r doesn't have permissions or roles = null -// System.out.println(e.toString()); -// return null; -// } -// -// return new UsernamePasswordAuthenticationToken(employeeId, pwd, authorities); -// } else { -// throw new BadCredentialsException("Invalid password!"); -// } -// } else { -// throw new BadCredentialsException("No user registered with this details!"); -// } -// -// } -// -// //customer -// User customer = null; -// try { -// customer = userRepository.getUserDetailsByUserName(username); -// -// } catch (Exception e) { -// throw new BadCredentialsException("No user registered with this details!"); -// } -// -// //if the person exists -// if (customer != null) { -// System.out.println(customer.getPassword()); -// -// //check for a match -// if (passwordEncoder.matches(pwd, customer.getPassword())) { -// -// //then it is a match a number of springs granted authorities -// List authorities = new ArrayList<>(); -// -// //loop through the users authorities and add each of them to simple granted authority -// try { -// customer.getRoles().forEach(a -> authorities.add(new SimpleGrantedAuthority(a.getRole()))); -// } catch (Exception e) { -// //user doesn't have permissions or roles = null -// System.out.println(e.toString()); -// return null; -// } -// //final send the username password and auth as a token which will call the authenticate method in the ProviderManager -// // in this edit i wont store the password but a use id -// -// //this is so that i can get a global access to an authenticated users name and id -// username = username + "," + customer.getId() + "," + customer.getUserAccountId().getId(); -// -// return new UsernamePasswordAuthenticationToken(username, pwd, authorities); -// } else { -// throw new BadCredentialsException("Invalid password!"); -// } -// } else { -// throw new BadCredentialsException("No user registered with this details!"); -// } -// } -// -// @Override -// public boolean supports(Class authentication) { -// //tells spring that i want to support username password style of auth -// return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); -// } -// -//} +package com.example.cezenPBX.config; + +import com.example.cezenPBX.DAO.UserOpsDAO; +import com.example.cezenPBX.entity.user.UserEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class CustomAuthenticationProviderForCezen implements AuthenticationProvider { + + @Autowired + private UserOpsDAO userOpsDAO; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + + //get credentials from login form + String username = authentication.getName(); + String pwd = authentication.getCredentials().toString(); + + //sanity check + if (username.isEmpty() || pwd.isEmpty()) return null; + + //check for employee + UserEntity user = null; + try { + //check if employee exists if yes then fetch details + user = this.userOpsDAO.getUserByUserName(username); + } catch (Exception e) { + System.out.println(e.toString()); + return null; + } + + if (passwordEncoder.matches(pwd, user.getPassword())) { + + //then it is a match a number of springs granted authorities + List authorities = new ArrayList<>(); + + //loop through the users authorities and add each of them to simple granted authority + try { + //check if user is part of permission set for admin signing in + boolean isAdmin = false; + for(var permission : user.getRoles()){ + if(permission.getRole().equals("ROLE_admin")) isAdmin = true; + } + if(!isAdmin) throw new BadCredentialsException("no employee permission for given employee"); + + user.getRoles().forEach(a -> authorities.add(new SimpleGrantedAuthority(a.getRole()))); + } catch (Exception e) { + //use/**/r doesn't have permissions or roles = null + System.out.println(e.toString()); + return null; + } + + return new UsernamePasswordAuthenticationToken(user, pwd, authorities); + } else { + throw new BadCredentialsException("Invalid password!"); + } + } + + @Override + public boolean supports(Class authentication) { + //tells spring that i want to support username password style of auth + return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); + } + +} diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/controller/SignUpController.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/controller/SignUpController.java index 34f2814..d78b506 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/controller/SignUpController.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/controller/SignUpController.java @@ -5,10 +5,7 @@ import com.example.cezenPBX.DTO.user.AdminSetPasswordDTO; import com.example.cezenPBX.service.PbxUserService; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/open") @@ -30,6 +27,10 @@ public class SignUpController { } // and a login route + @GetMapping("/login") + public ReturnStatus login(){ + return new ReturnStatus(false, "Login not yet implemented", "Login not yet implemented"); + } diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenGeneratorFilter.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenGeneratorFilter.java index e1d8be5..d2b5838 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenGeneratorFilter.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenGeneratorFilter.java @@ -66,7 +66,8 @@ public class JWTTokenGeneratorFilter extends OncePerRequestFilter { @Override protected boolean shouldNotFilter(HttpServletRequest request) { - return (request.getServletPath().equals("/open/signup") || request.getServletPath().equals("/open/employee-login")); + return !request.getServletPath().equals("/open/login"); + //return !(request.getServletPath().equals("/open/signup") || request.getServletPath().equals("/open/login")); } // gets the authority's from granted authority which we set in the configuration CustomAuthenticationProvider class diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenValidatorFilter.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenValidatorFilter.java index 60e23df..9390541 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenValidatorFilter.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/security/JWTTokenValidatorFilter.java @@ -74,7 +74,7 @@ public class JWTTokenValidatorFilter extends OncePerRequestFilter { protected boolean shouldNotFilter(HttpServletRequest request) { return request.getServletPath().equals("/open/signup") - || request.getServletPath().equals("/employee/employee-login"); + || request.getServletPath().equals("/open/login"); // //bellow was done to archive this /exposed/** // request.getServletPath().split("/")[1].equals("exposed"); } diff --git a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/service/PbxUserService.java b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/service/PbxUserService.java index d74c4d9..7534b1d 100644 --- a/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/service/PbxUserService.java +++ b/MySQL_conf_pbx/test1/springCezenPBX/src/main/java/com/example/cezenPBX/service/PbxUserService.java @@ -2,7 +2,6 @@ package com.example.cezenPBX.service; import com.example.cezenPBX.DAO.UserOpsDAO; import com.example.cezenPBX.DTO.ReturnStatus; -import com.example.cezenPBX.entity.user.Role; import com.example.cezenPBX.entity.user.UserEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; @@ -28,9 +27,9 @@ public class PbxUserService { return new ReturnStatus(false, "Passwords do not match", "Passwords do not match"); } // password encryption - UserEntity userEntity = new UserEntity(userName, "{bcrypt}"+passwordEncoder.encode(password), email); + UserEntity userEntity = new UserEntity(userName, passwordEncoder.encode(password), email); // commit the username and password to the database - return userOpsDAO.adminSetPasswordToDb(userEntity); + return userOpsDAO.adminSetUsernameAndPassword(userEntity); } }