diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml new file mode 100644 index 0000000..a37bc83 --- /dev/null +++ b/.idea/dataSources.local.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..eff9a4d --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + { + "lastFilter": { + "state": "OPEN", + "assignee": "doaa-shafi" + } +} + { + "selectedUrlAndAccountId": { + "url": "https://github.com/HubStaff-MSA/UserAppMicroService.git", + "accountId": "1e500e95-6352-4538-8934-ef6d2e5c5d11" + } +} + + + { + "associatedIndex": 8 +} + + + + { + "keyToString": { + "RunOnceActivity.ShowReadmeOnStart": "true", + "git-widget-placeholder": "roba", + "kotlin-language-version-configured": "true", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "run.configurations.included.in.services": "true", + "vue.rearranger.settings.migration": "true" + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1715981610166 + + + + + + + + + \ No newline at end of file diff --git a/config-server/target/classes/application.properties b/config-server/target/classes/application.properties new file mode 100644 index 0000000..d2c7449 --- /dev/null +++ b/config-server/target/classes/application.properties @@ -0,0 +1 @@ +spring.application.name=config-server diff --git a/config-server/target/classes/com/roba/configserver/ConfigServerApplication.class b/config-server/target/classes/com/roba/configserver/ConfigServerApplication.class new file mode 100644 index 0000000..c63e942 Binary files /dev/null and b/config-server/target/classes/com/roba/configserver/ConfigServerApplication.class differ diff --git a/security/security/pom.xml b/security/security/pom.xml index 883c7c5..e6c9c35 100644 --- a/security/security/pom.xml +++ b/security/security/pom.xml @@ -50,6 +50,12 @@ jjwt-impl 0.11.5 + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + + org.springframework.boot spring-boot-starter-test @@ -60,6 +66,8 @@ spring-security-test test + + diff --git a/security/security/src/main/java/com/roba/security/Client/Client.java b/security/security/src/main/java/com/roba/security/Client/Client.java new file mode 100644 index 0000000..25eca0a --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Client/Client.java @@ -0,0 +1,54 @@ +package com.roba.security.Client; + +import com.roba.security.Project.BudgetBasedOn; +import com.roba.security.Project.BudgetType; +import com.roba.security.Project.Project; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.antlr.v4.runtime.misc.NotNull; + +import java.util.Date; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Table(name = "Client") +public class Client { + @Id + @SequenceGenerator( + name = "client_id_sequence", + sequenceName = "client_id_sequence" + ) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "client_id_sequence" + ) + private Integer id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String email; + + @NotNull + @OneToMany(mappedBy = "client", cascade = CascadeType.ALL) + private List projects; + private String phoneNumber; + private String emailAddress; + //private Budget budget; + private boolean billable; + private BudgetType budgetType; + private BudgetBasedOn budgetBasedOn; + private Double budgetCost; + private Double budgetNotifyAt; + private Date budgetStartDate; + private boolean budgetIncludeNonBillabeTime; + private Integer organizationId; +} \ No newline at end of file diff --git a/security/security/src/main/java/com/roba/security/JwtService.java b/security/security/src/main/java/com/roba/security/JwtService.java deleted file mode 100644 index 4ea89c9..0000000 --- a/security/security/src/main/java/com/roba/security/JwtService.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.roba.security; - -import org.springframework.stereotype.Service; - -@Service -public class JwtService { - - - public String extractEmail(String token) { - return null; - } -} diff --git a/security/security/src/main/java/com/roba/security/Project/BudgetBasedOn.java b/security/security/src/main/java/com/roba/security/Project/BudgetBasedOn.java new file mode 100644 index 0000000..4e018e6 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/BudgetBasedOn.java @@ -0,0 +1,4 @@ +package com.roba.security.Project; + +public enum BudgetBasedOn { +} diff --git a/security/security/src/main/java/com/roba/security/Project/BudgetType.java b/security/security/src/main/java/com/roba/security/Project/BudgetType.java new file mode 100644 index 0000000..cdd2421 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/BudgetType.java @@ -0,0 +1,4 @@ +package com.roba.security.Project; + +public enum BudgetType { +} diff --git a/security/security/src/main/java/com/roba/security/Project/Project.java b/security/security/src/main/java/com/roba/security/Project/Project.java new file mode 100644 index 0000000..1f58074 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/Project.java @@ -0,0 +1,57 @@ +package com.roba.security.Project; + + + +import com.roba.security.Client.Client; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.antlr.v4.runtime.misc.NotNull; + +import java.util.Date; +//import javax.*; + + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Table(name = "Project") +public class Project { + @Id + @SequenceGenerator( + name = "project_id_sequence", + sequenceName = "project_id_sequence" + ) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "project_id_sequence" + ) + private Integer id; + // @NotNull + private String projectName; + private boolean disableActivity; + private boolean disableIdleTime; + //private Integer clientId; + @ManyToOne + @JoinColumn(name = "client_id", nullable = false) + private Client client; + // @NotNull + //private Budget budget; + private boolean billable; + private BudgetType budgetType; + private BudgetBasedOn budgetBasedOn; + private Double budgetCost; + private Double budgetNotifyAt; + private Date budgetStartDate; + private boolean budgetIncludeNonBillabeTime; + // @NotNull + private Integer organizationId; + //members + //users + //managers + //CONSTRAINTS +} \ No newline at end of file diff --git a/security/security/src/main/java/com/roba/security/Project/ProjectController.java b/security/security/src/main/java/com/roba/security/Project/ProjectController.java new file mode 100644 index 0000000..8c8a43e --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/ProjectController.java @@ -0,0 +1,42 @@ +package com.roba.security.Project; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@Slf4j +@RestController +@RequestMapping("api/v1/project") +public record ProjectController(ProjectService projectService) { + + @PostMapping + public void createProject(@RequestBody ProjectCreationRequest projectRequest){ + System.out.printf("new project added {}", projectRequest); + projectService.createProject(projectRequest); + } + @PutMapping + public void editProject(@RequestBody ProjectEditRequest projectRequest){ + //log.info("project edited {}", projectRequest); + projectService.editProject(projectRequest); + } + @GetMapping + public Optional findById(@RequestParam Integer id){ + //log.info("find project {}", id); + return projectService.findById(id); + } + + +// @GetMapping("/{managerId}") +// public List findByManagerId(@PathVariable Integer managerId){ +// //log.info("find project {}", id); +// return projectService.findAllByManager(managerId); +// } + @DeleteMapping + public void deleteProject(@RequestParam Integer id){ + //log.info("project deleted {}", id); + projectService.deleteProject(id); + } + +} \ No newline at end of file diff --git a/security/security/src/main/java/com/roba/security/Project/ProjectCreationRequest.java b/security/security/src/main/java/com/roba/security/Project/ProjectCreationRequest.java new file mode 100644 index 0000000..5b613f3 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/ProjectCreationRequest.java @@ -0,0 +1,25 @@ +package com.roba.security.Project; + + + +import com.roba.security.Client.Client; + +import java.util.Date; + +public record ProjectCreationRequest( + String projectName, + boolean disableActivity, + boolean disableIdleTime, + //Integer clientId, + Client client, + boolean billable, + BudgetType budgetType, + BudgetBasedOn budgetBasedOn, + Double budgetCost, + Double budgetNotifyAt, + Date budgetStartDate, + boolean budgetIncludeNonBillabeTime, + //Budget budget, + Integer organizationId +) { +} \ No newline at end of file diff --git a/security/security/src/main/java/com/roba/security/Project/ProjectEditRequest.java b/security/security/src/main/java/com/roba/security/Project/ProjectEditRequest.java new file mode 100644 index 0000000..959cdf6 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/ProjectEditRequest.java @@ -0,0 +1,25 @@ +package com.roba.security.Project; + + +import com.roba.security.Client.Client; + +import java.util.Date; + +public record ProjectEditRequest( + Integer id, + String projectName, + //Budget budget, + boolean disableActivity, + boolean disableIdleTime, + //Integer clientId, + Client client, + boolean billable, + BudgetType budgetType, + BudgetBasedOn budgetBasedOn, + Double budgetCost, + Double budgetNotifyAt, + Date budgetStartDate, + boolean budgetIncludeNonBillabeTime, + Integer organizationId +) { +} \ No newline at end of file diff --git a/security/security/src/main/java/com/roba/security/Project/ProjectRepository.java b/security/security/src/main/java/com/roba/security/Project/ProjectRepository.java new file mode 100644 index 0000000..f415ac4 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/ProjectRepository.java @@ -0,0 +1,9 @@ +package com.roba.security.Project; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ProjectRepository extends JpaRepository { + // List findAllByManagerId(Integer managerId); +} \ No newline at end of file diff --git a/security/security/src/main/java/com/roba/security/Project/ProjectService.java b/security/security/src/main/java/com/roba/security/Project/ProjectService.java new file mode 100644 index 0000000..4d4acd3 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/Project/ProjectService.java @@ -0,0 +1,72 @@ +package com.roba.security.Project; + + + +import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Optional; + +@Service +public record ProjectService(ProjectRepository projectRepository) { + public void createProject(ProjectCreationRequest projectRequest) { + if (projectRequest.projectName() == null || projectRequest.projectName().isEmpty()) { + throw new IllegalArgumentException("Project name cannot be empty"); + } + Project project = Project.builder() + .projectName(projectRequest.projectName()) + .billable(projectRequest.billable()) + .budgetBasedOn(projectRequest.budgetBasedOn()) + .budgetCost(projectRequest.budgetCost()) + .budgetNotifyAt(projectRequest.budgetNotifyAt()) + .budgetStartDate(projectRequest.budgetStartDate()) + .budgetType(projectRequest.budgetType()) + .client(projectRequest.client()) + //.clientId(projectRequest.clientId()) + .budgetIncludeNonBillabeTime(projectRequest.budgetIncludeNonBillabeTime()) + .disableActivity(projectRequest.disableActivity()) + .disableIdleTime(projectRequest.disableIdleTime()) + .organizationId(projectRequest.organizationId()) + //.budget(projectRequest.budget()) + .build(); + //todo: check constraints + //todo: fix pgadmin bug + projectRepository.save(project); + } + public void editProject(ProjectEditRequest projectRequest) { + //Project project = projectRepository.getById(projectRequest.id()); + Project project = Project.builder() + .id(projectRequest.id()) + .projectName(projectRequest.projectName()) + .billable(projectRequest.billable()) + .budgetBasedOn(projectRequest.budgetBasedOn()) + .budgetCost(projectRequest.budgetCost()) + .budgetNotifyAt(projectRequest.budgetNotifyAt()) + .budgetStartDate(projectRequest.budgetStartDate()) + .budgetType(projectRequest.budgetType()) + //.clientId(projectRequest.clientId()) + .client(projectRequest.client()) + .budgetIncludeNonBillabeTime(projectRequest.budgetIncludeNonBillabeTime()) + .disableActivity(projectRequest.disableActivity()) + .disableIdleTime(projectRequest.disableIdleTime()) + .organizationId(projectRequest.organizationId()) +// .budget(projectRequest.budget()) + .build(); + //todo: check constraints + //todo: fix pgadmin bug + projectRepository.save(project); + } + public void deleteProject(Integer id){ + try { + projectRepository.deleteById(id); + } catch (Exception e) { + // Handle exception + throw new RuntimeException("Failed to delete project with id: " + id, e); + } + } + public Optional findById(Integer id){ + return projectRepository.findById(id); + } +// public List findAllByManager(Integer managerId){ +// return projectRepository.findAllByManagerId(managerId); +// } +} \ No newline at end of file diff --git a/security/security/src/main/java/com/roba/security/SecurityApplication.java b/security/security/src/main/java/com/roba/security/SecurityApplication.java index 4fac3e2..245fa5a 100644 --- a/security/security/src/main/java/com/roba/security/SecurityApplication.java +++ b/security/security/src/main/java/com/roba/security/SecurityApplication.java @@ -2,7 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +@EnableCaching @SpringBootApplication public class SecurityApplication { diff --git a/security/security/src/main/java/com/roba/security/UserRespository.java b/security/security/src/main/java/com/roba/security/UserRespository.java deleted file mode 100644 index cdbbee5..0000000 --- a/security/security/src/main/java/com/roba/security/UserRespository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.roba.security; - -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface UserRespository extends JpaRepository { - Optional findByEmail(String workEmail); -} diff --git a/security/security/src/main/java/com/roba/security/auth/AuthenticationController.java b/security/security/src/main/java/com/roba/security/auth/AuthenticationController.java new file mode 100644 index 0000000..e95bc9e --- /dev/null +++ b/security/security/src/main/java/com/roba/security/auth/AuthenticationController.java @@ -0,0 +1,54 @@ +package com.roba.security.auth; + +import com.roba.security.user.Command; +import com.roba.security.user.CommandFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/auth") +@RequiredArgsConstructor +public class AuthenticationController { + private final AuthenticationService service; + private final CommandFactory commandFactory; + +// @PostMapping("/register") +// public ResponseEntity register(@RequestBody RegisterRequest request) { +// Command command = commandFactory.createRegisterCommand(request); +// command.execute(); +// //return ResponseEntity.ok().build(); +// return ResponseEntity.ok(service.register(request)); +// } +// +// +// @PostMapping("/authenticate") +// public ResponseEntity authenticate(@RequestBody AuthenticationRequest request) { +// Command command = commandFactory.createAuthenticateCommand(request); +// command.execute(); +// //return ResponseEntity.ok().build(); +// return ResponseEntity.ok(service.authenticate(request)); +// } + + + @PostMapping("/register") + public ResponseEntity register(@RequestBody RegisterRequest request) { + Command command = commandFactory.createRegisterCommand(request); + command.execute(); + AuthenticationResponse response = command.getResult(); + return ResponseEntity.ok(response); + } + + @PostMapping("/authenticate") + public ResponseEntity authenticate(@RequestBody AuthenticationRequest request) { + Command command = commandFactory.createAuthenticateCommand(request); + command.execute(); + AuthenticationResponse response = command.getResult(); + return ResponseEntity.ok(response); + } + + + +} diff --git a/security/security/src/main/java/com/roba/security/auth/AuthenticationRequest.java b/security/security/src/main/java/com/roba/security/auth/AuthenticationRequest.java new file mode 100644 index 0000000..824e757 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/auth/AuthenticationRequest.java @@ -0,0 +1,16 @@ +package com.roba.security.auth; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AuthenticationRequest { + private String workEmail; + private String password; + +} diff --git a/security/security/src/main/java/com/roba/security/auth/AuthenticationResponse.java b/security/security/src/main/java/com/roba/security/auth/AuthenticationResponse.java new file mode 100644 index 0000000..022f994 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/auth/AuthenticationResponse.java @@ -0,0 +1,14 @@ +package com.roba.security.auth; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AuthenticationResponse { + private String token; +} diff --git a/security/security/src/main/java/com/roba/security/auth/AuthenticationService.java b/security/security/src/main/java/com/roba/security/auth/AuthenticationService.java new file mode 100644 index 0000000..c69616a --- /dev/null +++ b/security/security/src/main/java/com/roba/security/auth/AuthenticationService.java @@ -0,0 +1,232 @@ +package com.roba.security.auth; + +import com.roba.security.Project.Project; +import com.roba.security.config.JwtService; + +import java.util.Optional; +import com.roba.security.organization.Organization; +import com.roba.security.organization.OrganizationRepository; +import com.roba.security.token.Token; +import com.roba.security.token.TokenRepository; +import com.roba.security.token.TokenService; +import com.roba.security.token.TokenType; +import com.roba.security.user.*; +import lombok.RequiredArgsConstructor; + +import org.springframework.cache.annotation.Cacheable; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + + +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor + +public class AuthenticationService { + private final UserRepository repository; + private final PasswordEncoder passwordEncoder; + private final JwtService jwtService; + private final AuthenticationManager authenticationManager; + private final TokenRepository tokenRepository; + private final TokenService tokenService; + private final Emailvalidator emailvalidator; + private final OrganizationRepository organizationRepository; + + // @Cacheable(key="#id",value="User") + public AuthenticationResponse register(RegisterRequest request) { + //boolean isValidEmail =emailvalidator.test(request.getWorkEmail()); + //if(!isValidEmail) {throw new IllegalStateException("Invalid email");} + Optional existingUser = repository.findByworkEmail(request.getWorkEmail()); + if (existingUser.isPresent()) { + throw new IllegalStateException("Email is already in use"); + } + Role role; + if (request.getRole().equals("team_member")) { + role = Role.USER; + } else { + role = request.getRole(); + } + if (role == Role.OWNER) { + // Create organization + Organization organization = Organization.builder() + .name(request.getOrganizationName()) + .teamSize(request.getTeamSize()) + .websiteURL(request.getWebsite())// Assuming organization name is provided in the request + .build(); + Organization savedOrganization = organizationRepository.save(organization); + + var user = User.builder() + .fullName(request.getFullName()) + .workEmail(request.getWorkEmail()) + .password(passwordEncoder.encode(request.getPassword())) + .role(request.getRole()) + .organization(savedOrganization) + .build(); + var savedUser = repository.save(user); + var jwtToken = jwtService.generateToken(user); + + saveUserToken(savedUser, jwtToken); + return AuthenticationResponse.builder().token(jwtToken).build(); + } else if (role == Role.USER) { + // Fetch organization by name + Optional organizationOptional = organizationRepository.findByName(request.getOrganizationName()); + if (organizationOptional.isEmpty()) { + throw new IllegalStateException("Organization not found"); + } + Organization organization = organizationOptional.get(); + + var user = User.builder() + .fullName(request.getFullName()) + .workEmail(request.getWorkEmail()) + .password(passwordEncoder.encode(request.getPassword())) + .role(Role.USER) + .organization(organization) + .build(); + var savedUser = repository.save(user); + var jwtToken = jwtService.generateToken(user); + + saveUserToken(savedUser, jwtToken); + + return AuthenticationResponse.builder().token(jwtToken).build(); + } else { + throw new IllegalStateException("Role not supported"); + + } + + } + + private void revokeAllUserTokens(User user) { + var validUserTokens = tokenRepository.findAllValidTokenByUser(user.getId()); + if (validUserTokens.isEmpty()) + return; + validUserTokens.forEach(token -> { + token.setExpired(true); + token.setRevoked(true); + }); + tokenRepository.saveAll(validUserTokens); + } + + + public AuthenticationResponse authenticate(AuthenticationRequest request) { + authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + request.getWorkEmail(), + request.getPassword() + ) + ); + var user = repository.findByworkEmail(request.getWorkEmail()) + .orElseThrow(); + var jwtToken = jwtService.generateToken(user); + revokeAllUserTokens(user); + saveUserToken(user, jwtToken); + + return AuthenticationResponse.builder().token(jwtToken).build(); + + } + + private void saveUserToken(User user, String jwtToken) { + var token = Token.builder().user(user).token(jwtToken).tokenType(TokenType.BEARER).revoked(false).expired(false).build(); + tokenRepository.save(token); + tokenService.saveToken(token); + } + + +/////////profile edits + +// public String updateUserProfile(Integer userId, UserProfileUpdateRequest request) { +// User user = repository.findById(userId) +// .orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + userId)); +// if (request.getFullName() != null) { +// user.setFullName(request.getFullName()); +// } +// if (request.getWorkEmail() != null) { +// user.setWorkEmail(request.getWorkEmail()); +// } +// +// repository.save(user); +// return ""; +// + + + public String updateUserProfile(Integer userId, UserProfileUpdateRequest request) { + User user = repository.findById(userId) + .orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + userId)); + + // Update user profile fields if provided in the request + if (request.getFullName() != null) { + user.setFullName(request.getFullName()); + } + if (request.getWorkEmail() != null) { + user.setWorkEmail(request.getWorkEmail()); + } + + // Save the updated user record + User savedUser = repository.save(user); + + // Refresh the associated token(s) to prevent expiration + refreshUserTokens(savedUser); + + return "Profile updated successfully"; + } + + private void refreshUserTokens(User user) { + List userTokens = tokenRepository.findByUser(user); + userTokens.forEach(token -> { + token.setExpired(false); // Set the token as not expired + tokenRepository.save(token); // Save the refreshed token + tokenService.saveToken(token); + }); + + + + + + + + +} + + public void changeUserPassword(Integer userId, ChangePasswordRequest request) { + User user = repository.findById(userId) + .orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + userId)); + + + + + // Check if the current password matches + if (!passwordEncoder.matches(request.getCurrentPassword(), user.getPassword())) { + throw new UnauthorizedException("Current password is incorrect"); + } + // Update password + user.setPassword(passwordEncoder.encode(request.getNewPassword())); + + repository.save(user); + } + + + + + + + + + + //get all users + public List getAllUsers() { + return repository.findAll(); + } + + public OptionalgetUserById(Integer userId) { + return repository.findById(userId); + // .orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + userId)); + } + public List getUsersByRole(Role role) { + return repository.findByRole(role); + } + + +} diff --git a/security/security/src/main/java/com/roba/security/auth/Emailvalidator.java b/security/security/src/main/java/com/roba/security/auth/Emailvalidator.java new file mode 100644 index 0000000..aaa8bfc --- /dev/null +++ b/security/security/src/main/java/com/roba/security/auth/Emailvalidator.java @@ -0,0 +1,13 @@ +package com.roba.security.auth; + +import org.springframework.stereotype.Service; + +import java.util.function.Predicate; +@Service +public class Emailvalidator implements Predicate { + + @Override + public boolean test(String s) { + return false; + } +} diff --git a/security/security/src/main/java/com/roba/security/auth/RegisterRequest.java b/security/security/src/main/java/com/roba/security/auth/RegisterRequest.java new file mode 100644 index 0000000..fd4eb33 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/auth/RegisterRequest.java @@ -0,0 +1,24 @@ +package com.roba.security.auth; + +import com.roba.security.organization.Organization; +import com.roba.security.user.Role; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class RegisterRequest { + private String fullName; + private String password; + private String workEmail; + private Role role; + private String organizationName; + private Integer teamSize; + private String website; + + +} diff --git a/security/security/src/main/java/com/roba/security/config/ApplicationConfig.java b/security/security/src/main/java/com/roba/security/config/ApplicationConfig.java new file mode 100644 index 0000000..86ce4ad --- /dev/null +++ b/security/security/src/main/java/com/roba/security/config/ApplicationConfig.java @@ -0,0 +1,49 @@ +package com.roba.security.config; + +import com.roba.security.user.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +@Configuration +@RequiredArgsConstructor +public class ApplicationConfig { + private final UserRepository repository; + @Bean + public UserDetailsService userDetailsService() { + return username -> repository.findByworkEmail(username) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + + } + @Bean + public AuthenticationProvider authenticationProvider(){ + DaoAuthenticationProvider authprovider = new DaoAuthenticationProvider(); + authprovider.setUserDetailsService(userDetailsService()); + authprovider.setPasswordEncoder(passwordEncoder()); + return authprovider; + + } + + + @Bean + public PasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { + return config.getAuthenticationManager(); + + } +} diff --git a/security/security/src/main/java/com/roba/security/config/JwtAuthenticationFilter.java b/security/security/src/main/java/com/roba/security/config/JwtAuthenticationFilter.java new file mode 100644 index 0000000..e8eae2c --- /dev/null +++ b/security/security/src/main/java/com/roba/security/config/JwtAuthenticationFilter.java @@ -0,0 +1,69 @@ +package com.roba.security.config; + +import com.roba.security.token.TokenRepository; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Component +@RequiredArgsConstructor +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + private final JwtService jwtService; + private final UserDetailsService userDetailsService; + private final TokenRepository tokenRepository; + + + + + + + + @Override + protected void doFilterInternal( + @NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain) throws ServletException, IOException { + final String authHeader = request.getHeader("Authorization"); + final String jwt; + final String workEmail; + if (authHeader == null || !authHeader.startsWith("Bearer ")) { + filterChain.doFilter(request, response); + return; + + } + jwt = authHeader.substring(7); + workEmail = jwtService.extractUsername(jwt); + if (workEmail != null && SecurityContextHolder.getContext().getAuthentication()==null) { + UserDetails userDetails = this.userDetailsService.loadUserByUsername(workEmail); + var isTokenValid =tokenRepository.findByToken(jwt) + .map(t -> !t.isExpired() && !t.isRevoked()) + .orElse(false); + if (jwtService.isTokenValid( jwt, userDetails) && isTokenValid ) { + UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( + userDetails, + null, + userDetails.getAuthorities() + ); + authToken.setDetails( + new WebAuthenticationDetailsSource().buildDetails(request) + ); + SecurityContextHolder.getContext().setAuthentication(authToken); + } + + } + filterChain.doFilter(request, response); + } +} diff --git a/security/security/src/main/java/com/roba/security/config/JwtService.java b/security/security/src/main/java/com/roba/security/config/JwtService.java new file mode 100644 index 0000000..2aa0217 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/config/JwtService.java @@ -0,0 +1,69 @@ +package com.roba.security.config; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import java.security.Key; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +@Service +public class JwtService { +public static final String SECRET_KEY="Hqj4ZSrMAhMvjEpAQMQb2FiHqeMNmJi7mvT5xArPVzdhVfYHvqL2ZnwWzjJ+mbb2"; + + public String extractUsername(String token) {///the email + return extractClaim(token,Claims::getSubject); + } + private Claims extractClaims(String token) { + return Jwts.parserBuilder(). + setSigningKey(getSigningKey()). + build(). + parseClaimsJws(token).getBody(); + } + + public T extractClaim(String token, FunctionclaimsResolver) { + final Claims claims = extractClaims(token); + return claimsResolver.apply(claims); + } + public String generateToken(UserDetails userDetails) { + return generateToken(new HashMap<>(),userDetails); + } + public String generateToken(Map extraClaims, + + UserDetails userDetails) { + return Jwts + .builder() + .setClaims(extraClaims) + .setSubject(userDetails.getUsername()) + .setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis()+1000*60*24)) + .signWith(getSigningKey(), SignatureAlgorithm.HS256).compact(); + } +public boolean isTokenValid(String token,UserDetails userDetails){ + final String email = extractUsername(token); + return (email.equals(userDetails.getUsername())) && !isTokenExpired(token); +} + + +public boolean isTokenExpired(String token) { + + return extractExpiration(token).before(new Date()); +} + + private Date extractExpiration(String token) { + return extractClaim(token,Claims::getExpiration); + + } + + private Key getSigningKey() { + byte[] keyBytes = Decoders.BASE64.decode(SECRET_KEY); + return Keys.hmacShaKeyFor(keyBytes); + } +} diff --git a/security/security/src/main/java/com/roba/security/config/LogoutService.java b/security/security/src/main/java/com/roba/security/config/LogoutService.java new file mode 100644 index 0000000..7f18258 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/config/LogoutService.java @@ -0,0 +1,39 @@ +package com.roba.security.config; + +import com.roba.security.token.TokenRepository; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutHandler; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class LogoutService implements LogoutHandler { + private final TokenRepository tokenRepository; + + + @Override + public void logout( + HttpServletRequest request, + HttpServletResponse response, + Authentication authentication) { + final String authHeader = request.getHeader("Authorization"); + final String jwt; + if (authHeader == null || !authHeader.startsWith("Bearer ")) { + return; + } + jwt = authHeader.substring(7); + var storedToken =tokenRepository.findByToken(jwt) + .orElse(null); + if (storedToken != null) { + storedToken.setRevoked(true); + storedToken.setExpired(true); + tokenRepository.save(storedToken); + } + + } + + +} diff --git a/security/security/src/main/java/com/roba/security/config/SecurityConfiguration.java b/security/security/src/main/java/com/roba/security/config/SecurityConfiguration.java new file mode 100644 index 0000000..16a752a --- /dev/null +++ b/security/security/src/main/java/com/roba/security/config/SecurityConfiguration.java @@ -0,0 +1,79 @@ +package com.roba.security.config; + + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutHandler; + + +import static com.roba.security.user.Permission.*; +import static com.roba.security.user.Role.ORGANIZATION_MANAGER; +import static com.roba.security.user.Role.OWNER; + +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor + +public class SecurityConfiguration { + private final JwtAuthenticationFilter jwtAuthFilter; + private final AuthenticationProvider authenticationProvider; + private final LogoutHandler logoutHandler; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + + .csrf(csrf -> csrf.disable()) // Disable CSRF protection + .authorizeHttpRequests(authorizeRequests -> + authorizeRequests + .requestMatchers("/api/v1/auth/**").permitAll()// Allow access to public endpoints + .requestMatchers("api/users/**").permitAll() + .requestMatchers("/api/v1/project/**").hasAnyRole(OWNER.name(),ORGANIZATION_MANAGER.name())//allow access by biz owner to admin endpoint + .requestMatchers(HttpMethod.GET,"/api/v1/project/**").hasAnyAuthority(PROJECT_READ.name()) + .requestMatchers(HttpMethod.PUT,"/api/v1/project/**").hasAnyAuthority(PROJECT_UPDATE.name()) + .requestMatchers(HttpMethod.POST,"/api/v1/project/**").hasAnyAuthority(PROJECT_CREATE.name()) + .requestMatchers(HttpMethod.DELETE,"/api/v1/project/**").hasAnyAuthority(PROJECT_DELETE.name()) + + .requestMatchers("/api/v1/payment/**").hasAnyRole(OWNER.name()) + .requestMatchers("/payroll/**").hasAnyRole(OWNER.name()) + .anyRequest().authenticated() // Require authentication for other requests + ) + .sessionManagement(sessionManagement -> + sessionManagement + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + ) + .authenticationProvider(authenticationProvider) + .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class) + .logout(logout -> // Customizing logout configuration + logout + .logoutUrl("/api/v1/auth/logout") + .addLogoutHandler(logoutHandler) + .logoutSuccessHandler( (request, response, authentication) -> SecurityContextHolder.clearContext())); + + + +// .logout() +// .logoutUrl("/api/v1/auth/logout") +// .addLogoutHandler(logoutHandler) +// .logoutSuccessHandler( +// (request, response, authentication) -> SecurityContextHolder.clearContext() +// ); + return http.build(); + } + + + + + + + +} diff --git a/security/security/src/main/java/com/roba/security/config_JwtAuthenticationFilter.java b/security/security/src/main/java/com/roba/security/config_JwtAuthenticationFilter.java deleted file mode 100644 index fade8e9..0000000 --- a/security/security/src/main/java/com/roba/security/config_JwtAuthenticationFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.roba.security; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; - -import java.io.IOException; - -@Component -@RequiredArgsConstructor -public class config_JwtAuthenticationFilter extends OncePerRequestFilter { - - private final JwtService jwtService; - - - - - - - @Override - protected void doFilterInternal( - @NonNull HttpServletRequest request, - @NonNull HttpServletResponse response, - @NonNull FilterChain filterChain) throws ServletException, IOException { - final String authHeader = request.getHeader("Authorization"); - final String jwt; - final String workEmail; - if (authHeader == null || !authHeader.startsWith("Bearer ")) { - filterChain.doFilter(request, response); - return; - - } - jwt = authHeader.substring(7); - workEmail = jwtService.extractEmail(jwt); - } -} diff --git a/security/security/src/main/java/com/roba/security/demo/DemoController.java b/security/security/src/main/java/com/roba/security/demo/DemoController.java new file mode 100644 index 0000000..9b15770 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/demo/DemoController.java @@ -0,0 +1,15 @@ +package com.roba.security.demo; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/demo-controller") +public class DemoController { + @GetMapping + public ResponseEntity sayHello() { + return ResponseEntity.ok("Hello from secured endpoint"); + } +} diff --git a/security/security/src/main/java/com/roba/security/demo/ProjectController1.java b/security/security/src/main/java/com/roba/security/demo/ProjectController1.java new file mode 100644 index 0000000..a528f11 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/demo/ProjectController1.java @@ -0,0 +1,24 @@ +package com.roba.security.demo; + + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/projects") + +public class ProjectController1 { + + + @GetMapping + public String get() { + return "get controller"; + } + + @PostMapping + public String post() { + return "post controller"; + } +} diff --git a/security/security/src/main/java/com/roba/security/organization/Organization.java b/security/security/src/main/java/com/roba/security/organization/Organization.java new file mode 100644 index 0000000..7dd5e36 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/organization/Organization.java @@ -0,0 +1,40 @@ +package com.roba.security.organization; + +import com.roba.security.user.User; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +public class Organization { + @Id + @SequenceGenerator( + name="organization_id_sequence", + sequenceName="organization_id_sequence" + ) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "organization_id_seqeunce" + ) + private Integer id; + private String name; + private String websiteURL; + private Integer teamSize; + private String industry; + @OneToMany(mappedBy = "organization") // mappedBy refers to the field in User entity that owns the relationship + private List users ; + + +// @OneToOne(mappedBy = "organization", cascade = CascadeType.ALL) +// private User manager; + + +} diff --git a/security/security/src/main/java/com/roba/security/organization/OrganizationRepository.java b/security/security/src/main/java/com/roba/security/organization/OrganizationRepository.java new file mode 100644 index 0000000..73d45ec --- /dev/null +++ b/security/security/src/main/java/com/roba/security/organization/OrganizationRepository.java @@ -0,0 +1,11 @@ +package com.roba.security.organization; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface OrganizationRepository extends JpaRepository { + Optional findByName(String organizationName); +} diff --git a/security/security/src/main/java/com/roba/security/organization/OrganizationService.java b/security/security/src/main/java/com/roba/security/organization/OrganizationService.java new file mode 100644 index 0000000..60301ef --- /dev/null +++ b/security/security/src/main/java/com/roba/security/organization/OrganizationService.java @@ -0,0 +1,20 @@ +package com.roba.security.organization; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class OrganizationService { + + private final OrganizationRepository organizationRepository; + @Autowired + public OrganizationService(OrganizationRepository organizationRepository) { + this.organizationRepository = organizationRepository; + } + + public List getAllOrganizations() { + return organizationRepository.findAll(); + } +} diff --git a/security/security/src/main/java/com/roba/security/token/RedisConfig.java b/security/security/src/main/java/com/roba/security/token/RedisConfig.java new file mode 100644 index 0000000..c319724 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/token/RedisConfig.java @@ -0,0 +1,30 @@ +package com.roba.security.token; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + @Bean + public JedisConnectionFactory jedisConnectionFactory() { + JedisConnectionFactory factory = new JedisConnectionFactory(); + factory.setHostName("redis-12006.c62.us-east-1-4.ec2.redns.redis-cloud.com"); + factory.setPort(12006); + factory.setPassword("oSrE2KvyJdxFJ8vmpDlIBDtQ9ZriadjR"); + return factory; + } + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(jedisConnectionFactory()); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + return template; + } +} diff --git a/security/security/src/main/java/com/roba/security/token/Token.java b/security/security/src/main/java/com/roba/security/token/Token.java new file mode 100644 index 0000000..98d44d4 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/token/Token.java @@ -0,0 +1,34 @@ +package com.roba.security.token; + +import com.roba.security.user.User; +import jakarta.persistence.*; +import lombok.*; +import java.io.Serializable; + +@Entity +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Token implements Serializable { + + private static final long serialVersionUID = 6529685098267757690L; // Add a serial version UID for serialization + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) // Make sure to specify the strategy explicitly if not default + private Integer id; + + private String token; + + @Enumerated(EnumType.STRING) + private TokenType tokenType; + + private boolean expired; + + private boolean revoked; + + @ManyToOne + @JoinColumn(name = "user_id") + private User user; // Ensure that the User class is also Serializable if it's being cached or stored + +} diff --git a/security/security/src/main/java/com/roba/security/token/TokenRepository.java b/security/security/src/main/java/com/roba/security/token/TokenRepository.java new file mode 100644 index 0000000..e3b294e --- /dev/null +++ b/security/security/src/main/java/com/roba/security/token/TokenRepository.java @@ -0,0 +1,21 @@ +package com.roba.security.token; + + +import com.roba.security.user.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import java.util.Optional; +import java.util.List; + +public interface TokenRepository extends JpaRepository { + + @Query(""" + select t from Token t inner join User u on t.user.id=u.id + where u.id=:userId and(t.expired=false or t.revoked=false) + """) + List findAllValidTokenByUser(Integer userId); + + Optional findByToken(String token); + + List findByUser(User user); +} diff --git a/security/security/src/main/java/com/roba/security/token/TokenService.java b/security/security/src/main/java/com/roba/security/token/TokenService.java new file mode 100644 index 0000000..1cae9f5 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/token/TokenService.java @@ -0,0 +1,41 @@ +package com.roba.security.token; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.concurrent.TimeUnit; + +@Service +public class TokenService { + + @Autowired + private RedisTemplate redisTemplate; + + // Save or update token in Redis and cache + @CachePut(value = "tokens", key = "#token.id") + public Token saveToken(Token token) { + redisTemplate.opsForValue().set(buildRedisKey(token.getId()), token, 30, TimeUnit.MINUTES); + return token; + } + + // Retrieve token from cache or Redis + @Cacheable(value = "tokens", key = "#id") + public Token getToken(Integer id) { + // This will only execute if the token is not found in the cache + return redisTemplate.opsForValue().get(buildRedisKey(id)); + } + + // Remove token from Redis and cache + @CacheEvict(value = "tokens", key = "#id") + public void deleteToken(Integer id) { + redisTemplate.delete(buildRedisKey(id)); + } + + private String buildRedisKey(Integer id) { + return "TOKEN_" + id; + } +} diff --git a/security/security/src/main/java/com/roba/security/token/TokenType.java b/security/security/src/main/java/com/roba/security/token/TokenType.java new file mode 100644 index 0000000..59f32a6 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/token/TokenType.java @@ -0,0 +1,5 @@ +package com.roba.security.token; + +public enum TokenType { + BEARER +} diff --git a/security/security/src/main/java/com/roba/security/user/AuthenticateCommand.java b/security/security/src/main/java/com/roba/security/user/AuthenticateCommand.java new file mode 100644 index 0000000..0d388e9 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/AuthenticateCommand.java @@ -0,0 +1,30 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationRequest; +import com.roba.security.auth.AuthenticationResponse; +import com.roba.security.auth.AuthenticationService; + +public class AuthenticateCommand implements Command { + private final AuthenticationService service; + private final AuthenticationRequest request; + private AuthenticationResponse result; + public AuthenticateCommand(AuthenticationService service, AuthenticationRequest request) { + this.service = service; + this.request = request; + } + + @Override + public void execute() { + result = service.authenticate(request); + } + @Override + public AuthenticationResponse getResult() { + return result; + } +} + + + + + + diff --git a/security/security/src/main/java/com/roba/security/user/ChangePasswordCommand.java b/security/security/src/main/java/com/roba/security/user/ChangePasswordCommand.java new file mode 100644 index 0000000..0774998 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/ChangePasswordCommand.java @@ -0,0 +1,28 @@ +package com.roba.security.user; + + +import com.roba.security.auth.AuthenticationResponse; +import com.roba.security.auth.AuthenticationService; + +public class ChangePasswordCommand implements Command { + private final AuthenticationService userService; + private final Integer userId; + private final ChangePasswordRequest request; + + public ChangePasswordCommand(AuthenticationService userService, Integer userId, ChangePasswordRequest request) { + this.userService = userService; + this.userId = userId; + this.request = request; + } + + @Override + public void execute() { + userService.changeUserPassword(userId, request); + } + + @Override + public AuthenticationResponse getResult() { + return null; + } +} + diff --git a/security/security/src/main/java/com/roba/security/user/ChangePasswordRequest.java b/security/security/src/main/java/com/roba/security/user/ChangePasswordRequest.java new file mode 100644 index 0000000..ae9b85e --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/ChangePasswordRequest.java @@ -0,0 +1,11 @@ +package com.roba.security.user; + + +import lombok.Data; + +@Data +public class ChangePasswordRequest { + private String currentPassword; + private String newPassword; + // private String workEmail; +} diff --git a/security/security/src/main/java/com/roba/security/user/Command.java b/security/security/src/main/java/com/roba/security/user/Command.java new file mode 100644 index 0000000..6362e4d --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/Command.java @@ -0,0 +1,8 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationResponse; + +public interface Command { + void execute(); + AuthenticationResponse getResult(); +} diff --git a/security/security/src/main/java/com/roba/security/user/CommandFactory.java b/security/security/src/main/java/com/roba/security/user/CommandFactory.java new file mode 100644 index 0000000..38d5d9d --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/CommandFactory.java @@ -0,0 +1,47 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationRequest; +import com.roba.security.auth.AuthenticationService; +import com.roba.security.auth.RegisterRequest; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Optional; + +@Component +public class CommandFactory { + private final AuthenticationService userService; + + public CommandFactory(AuthenticationService userService) { + this.userService = userService; + } + + public Command createUpdateProfileCommand(Integer userId, UserProfileUpdateRequest request) { + return new UpdateProfileCommand(userService, userId, request); + } + + public Command createChangePasswordCommand(Integer userId, ChangePasswordRequest request) { + return new ChangePasswordCommand(userService, userId, request); + } + public Command createGetAllUsersCommand() { + return new GetAllUsersCommand(userService); + } + public Command createGetUserByIdCommand(Integer userId) { + return new GetUserByIdCommand(userId, userService);} + + public Command createGetUsersByRoleCommand(Role role) { + return new GetUsersByRoleCommand(role, userService); + } + public Command createRegisterCommand(RegisterRequest request) { + return new RegisterCommand(userService, request); + } + + public Command createAuthenticateCommand(AuthenticationRequest request) { + return new AuthenticateCommand(userService, request); + } + + + + + +} diff --git a/security/security/src/main/java/com/roba/security/user/GetAllUsersCommand.java b/security/security/src/main/java/com/roba/security/user/GetAllUsersCommand.java new file mode 100644 index 0000000..5f7ea63 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/GetAllUsersCommand.java @@ -0,0 +1,24 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationResponse; +import com.roba.security.auth.AuthenticationService; + +import java.util.List; + +public class GetAllUsersCommand implements Command { + private final AuthenticationService userService; + + public GetAllUsersCommand(AuthenticationService userService) { + this.userService = userService; + } + + @Override + public void execute() { + userService.getAllUsers(); + } + + @Override + public AuthenticationResponse getResult() { + return null; + } +} diff --git a/security/security/src/main/java/com/roba/security/user/GetUserByIdCommand.java b/security/security/src/main/java/com/roba/security/user/GetUserByIdCommand.java new file mode 100644 index 0000000..6f601ad --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/GetUserByIdCommand.java @@ -0,0 +1,26 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationResponse; +import com.roba.security.auth.AuthenticationService; + +import java.util.Optional; + +public class GetUserByIdCommand implements Command { + private final Integer userId; + private final AuthenticationService userService; + + public GetUserByIdCommand(Integer userId, AuthenticationService userService) { + this.userId = userId; + this.userService = userService; + } + + @Override + public void execute() { + userService.getUserById(userId); + } + + @Override + public AuthenticationResponse getResult() { + return null; + } +} diff --git a/security/security/src/main/java/com/roba/security/user/GetUsersByRoleCommand.java b/security/security/src/main/java/com/roba/security/user/GetUsersByRoleCommand.java new file mode 100644 index 0000000..5aef022 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/GetUsersByRoleCommand.java @@ -0,0 +1,28 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationResponse; +import com.roba.security.auth.AuthenticationService; + +import java.util.List; + +public class GetUsersByRoleCommand implements Command { + + + private final Role role; + private final AuthenticationService userService; + + public GetUsersByRoleCommand(Role role, AuthenticationService userService) { + this.role = role; + this.userService = userService; + } + + @Override + public void execute() { + userService.getUsersByRole(role); + } + + @Override + public AuthenticationResponse getResult() { + return null; + } +} diff --git a/security/security/src/main/java/com/roba/security/user/Permission.java b/security/security/src/main/java/com/roba/security/user/Permission.java new file mode 100644 index 0000000..be24339 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/Permission.java @@ -0,0 +1,60 @@ +package com.roba.security.user; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum Permission { + + PROJECT_READ("project:read"), + PROJECT_UPDATE("project:update"), + PROJECT_CREATE("project:create"), + PROJECT_DELETE("project:delete"), + ORGANIZATION_CREATE("organization:create"), + ORGANIZATION_DELETE("organization:delete"), + ORGANIZATION_UPDATE("organization:update"),//INVITE USERS=ADD MEMBERS + ORGANIZATION_READ("organization:read"),//VIEW MEMBERS + + PAYMENT_CREATE("payment:create"), + PAYMEMT_DELETE("payment:delete"), + PAYMENT_UPDATE("payment:update"), + PAYMENT_READ("payment:read"), + + PAYROLL_CREATE("payment:create"), + PAYROLL_DELETE("payment:delete"), + PAYROLL_UPDATE("payment:update"), + PAYROLL_READ("payment:read"), + + TEAMINVOICE_CREATE("invoice:create"), + TEAMINVOICE_DELETE("invoice:delete"), + TEAMINVOICE_UPDATE("invoice:update"), + TEAMINVOICE_READ("invoice:read"), + + + CLIENTINVOICE_CREATE("invoice:create"), + CLIENTINVOICE_DELETE("invoice:delete"), + CLIENTINVOICE_UPDATE("invoice:update"), + CLIENTINVOICE_READ("invoice:read"), + + + TIMESHEET_CREATE("timesheets:create"), + TIMESHEET_DELETE("timesheets:delete"), + TIMESHEET_UPDATE("timesheets:update"), + TIMESHEET_READ("timesheets:read"), + REPORTS_CREATE("reports:create"), + REPORTS_DELETE("reports:delete"), + REPORTS_UPDATE("reports:update"), + REPORTS_READ("reports:read"), + + + + + + + ; + + + + @Getter + private final String permission; +} diff --git a/security/security/src/main/java/com/roba/security/user/RegisterCommand.java b/security/security/src/main/java/com/roba/security/user/RegisterCommand.java new file mode 100644 index 0000000..b4c7e4c --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/RegisterCommand.java @@ -0,0 +1,27 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationResponse; +import com.roba.security.auth.AuthenticationService; +import com.roba.security.auth.RegisterRequest; + +public class RegisterCommand implements Command { + private final AuthenticationService service; + private final RegisterRequest request; + private AuthenticationResponse result; + + public RegisterCommand(AuthenticationService service, RegisterRequest request) { + this.service = service; + this.request = request; + } + + @Override + public void execute() { + result = service.register(request); + } + @Override + public AuthenticationResponse getResult() { + return result; + } + + +} diff --git a/security/security/src/main/java/com/roba/security/user/ResourceNotFoundException.java b/security/security/src/main/java/com/roba/security/user/ResourceNotFoundException.java new file mode 100644 index 0000000..2f669eb --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/ResourceNotFoundException.java @@ -0,0 +1,12 @@ +package com.roba.security.user; + + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.NOT_FOUND) +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException(String message) { + super(message); + } +} diff --git a/security/security/src/main/java/com/roba/security/user/Role.java b/security/security/src/main/java/com/roba/security/user/Role.java new file mode 100644 index 0000000..e5ee41d --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/Role.java @@ -0,0 +1,47 @@ +package com.roba.security.user; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.roba.security.user.Permission.*; + + +@RequiredArgsConstructor + +public enum Role { + USER(Collections.emptySet()), + + OWNER(Set.of(PROJECT_READ, + PROJECT_UPDATE, + PROJECT_DELETE, + PROJECT_CREATE, + PAYMENT_READ, + PAYMENT_UPDATE, + PAYMENT_CREATE + + + )), + + ORGANIZATION_MANAGER(Set.of(PROJECT_READ, + PROJECT_UPDATE, + PROJECT_DELETE, + PROJECT_CREATE)), + PROJECT_MANAGER(Collections.emptySet()); + +@Getter +private final Set permissions; +public List getAuthorities(){ + var authorities=getPermissions() + .stream() + .map(permission -> new SimpleGrantedAuthority(permission.getPermission())) + .collect(Collectors.toList()); + authorities.add(new SimpleGrantedAuthority("ROLE_"+this.name())); + return authorities; + } +} diff --git a/security/security/src/main/java/com/roba/security/user/UnauthorizedException.java b/security/security/src/main/java/com/roba/security/user/UnauthorizedException.java new file mode 100644 index 0000000..0dfa3d2 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/UnauthorizedException.java @@ -0,0 +1,11 @@ +package com.roba.security.user; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.UNAUTHORIZED) +public class UnauthorizedException extends RuntimeException { + public UnauthorizedException(String message) { + super(message); + } +} diff --git a/security/security/src/main/java/com/roba/security/user/UpdateProfileCommand.java b/security/security/src/main/java/com/roba/security/user/UpdateProfileCommand.java new file mode 100644 index 0000000..10a83e1 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/UpdateProfileCommand.java @@ -0,0 +1,27 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationResponse; +import com.roba.security.auth.AuthenticationService; + +public class UpdateProfileCommand implements Command{ + private final AuthenticationService userService; + private final Integer userId; + private final UserProfileUpdateRequest request; + + + public UpdateProfileCommand(AuthenticationService userService, Integer userId, UserProfileUpdateRequest request) { + this.userService = userService; + this.userId = userId; + this.request = request; + } + + @Override + public void execute() { + userService.updateUserProfile(userId, request); + } + + @Override + public AuthenticationResponse getResult() { + return null; + } +} diff --git a/security/security/src/main/java/com/roba/security/User.java b/security/security/src/main/java/com/roba/security/user/User.java similarity index 50% rename from security/security/src/main/java/com/roba/security/User.java rename to security/security/src/main/java/com/roba/security/user/User.java index 42a8933..b749f62 100644 --- a/security/security/src/main/java/com/roba/security/User.java +++ b/security/security/src/main/java/com/roba/security/user/User.java @@ -1,13 +1,18 @@ -package com.roba.security; +package com.roba.security.user; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.roba.security.Project.Project; +import com.roba.security.organization.Organization; +import com.roba.security.token.Token; import jakarta.persistence.*; import lombok.*; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; -import javax.management.relation.Role; + +import java.io.Serializable; import java.time.LocalDate; import java.util.Collection; import java.util.List; @@ -20,7 +25,8 @@ @Builder @Data @Table(name="_user") -public class User implements UserDetails { +@EqualsAndHashCode +public class User implements UserDetails, Serializable { @Id @SequenceGenerator( name="user_id_sequence", @@ -36,13 +42,54 @@ public class User implements UserDetails { private String password; @Enumerated(EnumType.STRING) private Role role; - private LocalDate joinDate; - //foreign key to organization table - private Integer organizationId; + @OneToMany(mappedBy = "user") + @JsonIgnore + private List tokens; + + + + private String Department; + private String Position;//Title + + + @ManyToOne + @JoinColumn(name="organization_id") + // This specifies the foreign key column name in the User table + + @JsonIgnore + private Organization organization; // Reference to organization) + + + @OneToMany + private List projects; + private String TimeZone; + private LocalDate hireDate; + private double hourlyRate; + private double salary; + private String taxInfo; + private Integer usedTimeOff; + private Integer pendingTimeOff; + private Integer balanceTimeOff; + private double totalHoursWorked; + private double WeeklyLimit; + + + private LocalDate DateRemoved; + private String PayType;//hourly/fixed + private Integer BillRate; + + private Integer DailyLimit; + private boolean TrackingEnabled; + private boolean TimesheetsEnabled; + private String Status; + // private List teams; + + + @Override public Collection getAuthorities() { - return List.of(new SimpleGrantedAuthority(role.getRoleName())); + return role.getAuthorities(); } @Override diff --git a/security/security/src/main/java/com/roba/security/user/UserController.java b/security/security/src/main/java/com/roba/security/user/UserController.java new file mode 100644 index 0000000..f1dd4cd --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/UserController.java @@ -0,0 +1,83 @@ +package com.roba.security.user; + +import com.roba.security.auth.AuthenticationService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import java.util.Optional; +import java.util.List; + import com.roba.security.user.CommandFactory; +@RestController +@RequestMapping("/api/users") +@RequiredArgsConstructor +public class UserController { + + private final CommandFactory commandFactory; + // @Autowired + private final AuthenticationService userService; + + @PutMapping("/{userId}/profile") +// public ResponseEntity updateProfile(@PathVariable("userId") Integer userId, @RequestBody UserProfileUpdateRequest request) { +// System.out.println("gg"); +// userService.updateUserProfile(userId, request); +// return ResponseEntity.ok().build(); +// } + + public ResponseEntity updateProfile(@PathVariable("userId") Integer userId, @RequestBody UserProfileUpdateRequest request) { + Command command = commandFactory.createUpdateProfileCommand(userId, request); + command.execute(); + return ResponseEntity.ok().build(); + } + + + @PutMapping("/{userId}/password") +// public ResponseEntity changePassword(@PathVariable("userId") Integer userId, @RequestBody ChangePasswordRequest request) { +// userService.changeUserPassword(userId, request); +// return ResponseEntity.ok().build(); +// } + public ResponseEntity changePassword(@PathVariable("userId") Integer userId, @RequestBody ChangePasswordRequest request) { + Command command = commandFactory.createChangePasswordCommand(userId, request); + command.execute(); + return ResponseEntity.ok().build(); + } + + + @GetMapping("/all") + public List getAllUsers() { + Command command = commandFactory.createGetAllUsersCommand(); + command.execute(); + return userService.getAllUsers(); + } + + + @GetMapping("/{userId}") + @Cacheable(key="#id",value="User") + public Optional getUserById(@PathVariable Integer userId) { + Command command = commandFactory.createGetUserByIdCommand(userId); + command.execute(); + return userService.getUserById(userId); + } + + @GetMapping("/role/{role}") + public List getUsersByRole(@PathVariable Role role) { + Command command = commandFactory.createGetUsersByRoleCommand(role); + command.execute(); + return userService.getUsersByRole(role); + } + +// +// @DeleteMapping("/{userId}") +// public ResponseEntity deleteUserById(@PathVariable("userId") Integer userId) { +// Command command = commandFactory.createDeleteUserCommand(userId); +// command.execute(); +// userService.deleteUserById(userId); +// return ResponseEntity.ok().build(); +// } + + + + + +} diff --git a/security/security/src/main/java/com/roba/security/user/UserProfileUpdateRequest.java b/security/security/src/main/java/com/roba/security/user/UserProfileUpdateRequest.java new file mode 100644 index 0000000..955376e --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/UserProfileUpdateRequest.java @@ -0,0 +1,12 @@ +package com.roba.security.user; + +import lombok.Data; + +@Data +public class UserProfileUpdateRequest { + private String fullName; + private String WorkEmail; + + + // Add other fields as needed for profile update +} diff --git a/security/security/src/main/java/com/roba/security/user/UserRepository.java b/security/security/src/main/java/com/roba/security/user/UserRepository.java new file mode 100644 index 0000000..ce88755 --- /dev/null +++ b/security/security/src/main/java/com/roba/security/user/UserRepository.java @@ -0,0 +1,14 @@ +package com.roba.security.user; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface UserRepository extends JpaRepository { + Optional findByworkEmail(String workEmail); + + List findByRole(Role role); + + // Optional findByWorkEmail(String workEmail); +} diff --git a/security/security/src/main/resources/application.yml b/security/security/src/main/resources/application.yml index aa957fb..e6d1afc 100644 --- a/security/security/src/main/resources/application.yml +++ b/security/security/src/main/resources/application.yml @@ -22,6 +22,19 @@ spring: show_sql: true database: postgresql database-platform: org.hibernate.dialect.PostgreSQLDialect - + cache: + type: redis + redis: + host: redis-12006.c62.us-east-1-4.ec2.redns.redis-cloud.com + port: 12006 + password: oSrE2KvyJdxFJ8vmpDlIBDtQ9ZriadjR + database: 0 + timeout: 60000 # Optional: Timeout in milliseconds for connection (60 seconds) + jedis: + pool: + max-active: 8 + max-wait: -1ms + max-idle: 8 + min-idle: 0 diff --git a/user/src/main/java/com/roba/user/User.java b/user/src/main/java/com/roba/user/User.java index 2006641..946f6b2 100644 --- a/user/src/main/java/com/roba/user/User.java +++ b/user/src/main/java/com/roba/user/User.java @@ -1,34 +1,34 @@ -package com.roba.user; - -import jakarta.persistence.*; -import lombok.*; - -import java.time.LocalDate; - -@Entity -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -@Builder -@Data -@Table(name="_user") -public class User { - @Id - @SequenceGenerator( - name="user_id_sequence", - sequenceName="user_id_sequence" - ) - @GeneratedValue( - strategy = GenerationType.SEQUENCE, - generator = "user_id_seqeunce" - ) - private Integer id; - private String fullName; - private String workEmail; - private String password; - private String role; - private LocalDate joinDate; - private Integer organizationId; - -} +//package com.roba.user; +// +//import jakarta.persistence.*; +//import lombok.*; +// +//import java.time.LocalDate; +// +//@Entity +//@Getter +//@Setter +//@AllArgsConstructor +//@NoArgsConstructor +//@Builder +//@Data +//@Table(name="_user") +//public class User { +// @Id +// @SequenceGenerator( +// name="user_id_sequence", +// sequenceName="user_id_sequence" +// ) +// @GeneratedValue( +// strategy = GenerationType.SEQUENCE, +// generator = "user_id_seqeunce" +// ) +// private Integer id; +// private String fullName; +// private String workEmail; +// private String password; +// private String role; +// private LocalDate joinDate; +// private Integer organizationId; +// +//} diff --git a/user/src/main/java/com/roba/user/UserController.java b/user/src/main/java/com/roba/user/UserController.java index eb2e723..f4cfac6 100644 --- a/user/src/main/java/com/roba/user/UserController.java +++ b/user/src/main/java/com/roba/user/UserController.java @@ -1,36 +1,36 @@ -package com.roba.user; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - - -@RestController -@RequestMapping("api/v1/users") -@RequiredArgsConstructor -public class UserController { -private final UserService service; - private final UserService userService; - - @PostMapping - @ResponseStatus(HttpStatus.CREATED) -// public void save(@RequestBody User user){ -// service.saveUser(user); +//package com.roba.user; // +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +// +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.*; +// +//import java.util.List; +// +// +//@RestController +//@RequestMapping("api/v1/users") +//@RequiredArgsConstructor +//public class UserController { +//private final UserService service; +// private final UserService userService; +// +// @PostMapping +// @ResponseStatus(HttpStatus.CREATED) +//// public void save(@RequestBody User user){ +//// service.saveUser(user); +//// +//// } +// public void createUser(@RequestBody UserRequest userRequest){ +// userService.createUser(userRequest); +// +// } +// +// @GetMapping +// @ResponseStatus(HttpStatus.OK) +// public List getAllUsers(){ +// return userService.getAllUsers(); // } - public void createUser(@RequestBody UserRequest userRequest){ - userService.createUser(userRequest); - - } - - @GetMapping - @ResponseStatus(HttpStatus.OK) - public List getAllUsers(){ - return userService.getAllUsers(); - } -} +//} diff --git a/user/src/main/java/com/roba/user/UserRepository.java b/user/src/main/java/com/roba/user/UserRepository.java index f18c563..e6fc952 100644 --- a/user/src/main/java/com/roba/user/UserRepository.java +++ b/user/src/main/java/com/roba/user/UserRepository.java @@ -1,6 +1,6 @@ -package com.roba.user; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UserRepository extends JpaRepository { -} +//package com.roba.user; +// +//import org.springframework.data.jpa.repository.JpaRepository; +// +//public interface UserRepository extends JpaRepository { +//} diff --git a/user/src/main/java/com/roba/user/UserService.java b/user/src/main/java/com/roba/user/UserService.java index ae3ad91..ecbac7a 100644 --- a/user/src/main/java/com/roba/user/UserService.java +++ b/user/src/main/java/com/roba/user/UserService.java @@ -1,39 +1,39 @@ -package com.roba.user; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -@Slf4j -public class UserService { - - - private final UserRepository userRepository; -// public void saveUser(User user) { +//package com.roba.user; // +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.stereotype.Service; // +//import java.util.List; +// +//@Service +//@RequiredArgsConstructor +//@Slf4j +//public class UserService { +// +// +// private final UserRepository userRepository; +//// public void saveUser(User user) { +//// +//// +//// userRepository.save(user); +//// } +// +// public void createUser(UserRequest userRequest) { +// User user = User.builder().fullName(userRequest.getFullName()) +// .workEmail(userRequest.getWorkEmail()).password(userRequest.getPassword()).role(userRequest.getRole()).build(); // userRepository.save(user); +// log.info("is saved user: {}", user); // } - - public void createUser(UserRequest userRequest) { - User user = User.builder().fullName(userRequest.getFullName()) - .workEmail(userRequest.getWorkEmail()).password(userRequest.getPassword()).role(userRequest.getRole()).build(); - userRepository.save(user); - log.info("is saved user: {}", user); - } - - public List getAllUsers(){ - List users= userRepository.findAll(); - return users.stream().map(this::mapToUserResponse).toList(); - } - private UserResponse mapToUserResponse (User user ){ - return UserResponse.builder(). - id(user.getId()) - .fullName(user.getFullName()).workEmail(user.getWorkEmail()).password(user.getPassword()).role(user.getRole()).build(); - } - -} +// +// public List getAllUsers(){ +// List users= userRepository.findAll(); +// return users.stream().map(this::mapToUserResponse).toList(); +// } +// private UserResponse mapToUserResponse (User user ){ +// return UserResponse.builder(). +// id(user.getId()) +// .fullName(user.getFullName()).workEmail(user.getWorkEmail()).password(user.getPassword()).role(user.getRole()).build(); +// } +// +//}