Changeset 4d97b63 for jobvista-backend/src/main/java/mk
- Timestamp:
- 08/30/24 15:44:27 (3 months ago)
- Branches:
- main
- Parents:
- 0f0add0
- Location:
- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend
- Files:
-
- 4 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/JobvistaBackendApplication.java
r0f0add0 r4d97b63 27 27 admin.setEmail("admin@admin.com"); 28 28 admin.setHasAccess(true); 29 // admin.setName("admin");30 // admin.setSurname("admin");31 29 admin.setPassword(new BCryptPasswordEncoder().encode("admin")); 32 30 userRepository.save(admin); -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/config/SecurityConfiguration.java
r0f0add0 r4d97b63 33 33 .requestMatchers( 34 34 "/api/auth/**", 35 "/oauth2/**", 35 36 "/api/job-advertisements/**", 36 37 "/api/applications/**", 37 38 "/api/recruiter/**", 38 "/api/job-seeker/**" 39 "/api/job-seeker/**", 40 "/uploads/**" 39 41 ).permitAll() 40 42 .requestMatchers("/api/admin/**").hasAnyAuthority(Role.ROLE_ADMIN.name()) … … 46 48 .requestMatchers("/api/job-advertisements/edit/{id}").hasAnyAuthority(Role.ROLE_RECRUITER.name()) 47 49 .requestMatchers("/api/job-advertisements/delete/{id}").hasAnyAuthority(Role.ROLE_RECRUITER.name()) 48 .requestMatchers("/api/applications/{id}/update").hasAnyAuthority(Role.ROLE_RECRUITER.name()) 50 .requestMatchers("/api/applications/{id}/update").hasAnyAuthority(Role.ROLE_JOBSEEKER.name()) 51 .requestMatchers("/api/applications/update").hasAnyAuthority(Role.ROLE_RECRUITER.name()) 52 .requestMatchers("/uploads/applications/**").hasAnyAuthority(Role.ROLE_RECRUITER.name()) 49 53 .requestMatchers("/api/job-advertisements/{advertisement_id}/applications").hasAnyAuthority(Role.ROLE_RECRUITER.name()) 54 .requestMatchers("/api/job-advertisements/{advertisement_id}/applications/filtered").hasAnyAuthority(Role.ROLE_RECRUITER.name()) 50 55 .requestMatchers("/api/applications/submit").hasAnyAuthority(Role.ROLE_JOBSEEKER.name()) 51 56 .requestMatchers("/api/my-applications/{id}").hasAnyAuthority(Role.ROLE_JOBSEEKER.name()) 52 .anyRequest().authenticated()) 57 .requestMatchers("/api/my-applications/{id}/filtered").hasAnyAuthority(Role.ROLE_JOBSEEKER.name()) 58 .anyRequest().authenticated()) 53 59 .sessionManagement(manager -> manager.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) 54 60 .authenticationProvider(authenticationProvider()).addFilterBefore( 55 jwtAuthFilter, UsernamePasswordAuthenticationFilter.class 56 ); 61 jwtAuthFilter, UsernamePasswordAuthenticationFilter.class) 62 .oauth2Login(oauth2 -> oauth2 63 .defaultSuccessUrl("/api/auth/google", true) 64 ) 65 ; 66 57 67 return http.build(); 58 68 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/ApplicationController.java
r0f0add0 r4d97b63 30 30 } 31 31 32 @PostMapping("/my-applications/{id}/filtered") 33 public ResponseEntity<?> filterApplicationsByJobSeekerId(@PathVariable Long id, @RequestBody String status) { 34 List<ApplicationDetailsDTO> applicationList = applicationService.filterByJobSeekerId(id, status); 35 return new ResponseEntity<>(applicationList, HttpStatus.OK); 36 } 37 32 38 @GetMapping("/job-advertisements/{advertisement_id}/applications") 33 39 public ResponseEntity<?> findAllApplicationsByJobAdvertisementId(@PathVariable("advertisement_id") Long advertisementId) { … … 36 42 } 37 43 38 @PostMapping("/applications/{id}/update") 44 @PostMapping("/job-advertisements/{advertisement_id}/applications/filtered") 45 public ResponseEntity<?> filterApplicationsByJobAdvertisementId(@PathVariable("advertisement_id") Long advertisementId, @RequestBody String status) { 46 List<ApplicationDetailsDTO> applicationList = applicationService.filterByJobAdvertisementId(advertisementId, status); 47 return new ResponseEntity<>(applicationList, HttpStatus.OK); 48 } 49 50 @PostMapping("/applications/{id}/update/NOT-IN-USE") 39 51 public ResponseEntity<?> updateApplicationStatus(@PathVariable("id") Long applicaitonId, @RequestBody ApplicationStatusDTO appStatusDTO) { 40 52 ApplicationStatusDTO applicationStatusDTO = applicationService.updateApplicationStatus(applicaitonId,appStatusDTO.getStatus()); 41 53 return new ResponseEntity<>(applicationStatusDTO, HttpStatus.OK); 54 } 55 56 @PostMapping("/applications/update") 57 public ResponseEntity<?> updateApplications(@RequestBody List<ApplicationStatusDTO> changes) { 58 List<ApplicationStatusDTO> updatedApplications = applicationService.updateApplications(changes); 59 return new ResponseEntity<>(updatedApplications, HttpStatus.OK); 42 60 } 43 61 … … 66 84 return new ResponseEntity<>(applicationDetailsDTO, HttpStatus.OK); 67 85 } 86 87 @PostMapping("/applications/{id}/update") 88 public ResponseEntity<ApplicationDetailsDTO> updateApplication( 89 @PathVariable("id") Long applicationId, 90 @RequestParam("additionalFiles") MultipartFile[] additionalFiles) { 91 ApplicationDetailsDTO applicationDetailsDTO = applicationService.updateApplication(applicationId, additionalFiles); 92 return new ResponseEntity<>(applicationDetailsDTO, HttpStatus.OK); 93 } 94 95 @GetMapping("/applications/{id}/download-additional-files") 96 public ResponseEntity<List<String>> getAdditionalFilesUrls(@PathVariable("id") Long applicationId) { 97 List<String> fileUrls = applicationService.loadAdditionalFilesAsUrls(applicationId); 98 return ResponseEntity.ok(fileUrls); 99 } 100 68 101 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/AuthController.java
r0f0add0 r4d97b63 7 7 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.mappers.JobSeekerMapper; 8 8 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.mappers.RecruiterMapper; 9 9 10 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.AuthService; 11 10 12 import org.springframework.http.HttpStatus; 11 13 import org.springframework.http.ResponseEntity; 12 14 import org.springframework.web.bind.annotation.*; 15 16 import java.util.Map; 17 18 13 19 14 20 @RestController … … 42 48 return ResponseEntity.ok(authenticationService.refreshToken(refreshTokenRequest)); 43 49 } 50 51 @PostMapping("/google") 52 public ResponseEntity<?> googleSignIn(@RequestBody Map<String, String> token) { 53 return ResponseEntity.ok(authenticationService.googleSignIn(token)); 54 } 44 55 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/Application.java
r0f0add0 r4d97b63 9 9 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.JobAdvertisement; 10 10 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.JobSeeker; 11 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User;12 11 13 12 import java.time.LocalDateTime; 14 import java.util. HashMap;13 import java.util.ArrayList; 15 14 import java.util.List; 16 15 … … 45 44 private ApplicationStatus status; 46 45 46 private String response; 47 48 @ElementCollection 49 private List<String> additionalFilePaths; 50 47 51 public Application(JobSeeker jobSeeker, JobAdvertisement jobAdvertisement, List<String> answers, String message) { 48 52 this.jobSeeker = jobSeeker; … … 53 57 submittedOn = LocalDateTime.now(); 54 58 this.status = ApplicationStatus.PROPOSED; 59 this.response = ""; 60 this.additionalFilePaths = new ArrayList<>(); 55 61 } 56 62 … … 72 78 application.getMessage(), 73 79 application.getSubmittedOn(), 74 application.getStatus().name() 80 application.getStatus().name(), 81 application.getResponse(), 82 application.getAdditionalFilePaths() 75 83 ); 76 84 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationDetailsDTO.java
r0f0add0 r4d97b63 29 29 private LocalDateTime submittedOn; 30 30 private String status; 31 private String response; 32 private List<String> additionalFileNames; 31 33 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationStatusDTO.java
r0f0add0 r4d97b63 9 9 Long id; 10 10 String status; 11 String response; 11 12 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/repositories/JobSeekerRepository.java
r0f0add0 r4d97b63 4 4 import org.springframework.data.jpa.repository.JpaRepository; 5 5 6 import java.util.Optional; 7 6 8 public interface JobSeekerRepository extends JpaRepository<JobSeeker, Long> { 9 Optional<JobSeeker> findByEmail(String email); 7 10 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/ApplicationServiceImpl.java
r0f0add0 r4d97b63 6 6 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.JobSeeker; 7 7 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.JobSeekerRepository; 8 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.EmailSenderService; 8 9 import org.springframework.core.io.Resource; 9 10 import org.springframework.core.io.UrlResource; … … 19 20 import org.springframework.beans.factory.annotation.Value; 20 21 import org.springframework.stereotype.Service; 22 import org.springframework.web.multipart.MultipartFile; 23 import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 21 24 22 25 import java.io.IOException; 26 import java.net.MalformedURLException; 23 27 import java.nio.file.Files; 24 28 import java.nio.file.Path; … … 39 43 40 44 @Autowired 45 private EmailSenderService emailSenderService; 46 47 @Autowired 41 48 public ApplicationServiceImpl(@Value("${file.upload-dir}") String uploadDir, UserRepository userRepository, ApplicationRepository applicationRepository, JobAdvertisementRepository jobAdvertisementRepository, 42 49 JobSeekerRepository jobSeekerRepository) { … … 95 102 96 103 @Override 104 public ApplicationDetailsDTO updateApplication(Long applicationId, MultipartFile[] additionalFiles) { 105 Application application = applicationRepository.findById(applicationId).orElse(null); 106 if(application== null) { 107 throw new RuntimeException("Application not found."); 108 } 109 110 for (MultipartFile additionalFile : additionalFiles) { 111 if (additionalFile.isEmpty()) { 112 throw new RuntimeException("Failed to store empty file."); 113 } 114 } 115 116 Path filesPath = this.fileStorageLocation.resolve(String.valueOf(application.getId())).resolve("additional_files"); 117 for(MultipartFile additionalFile: additionalFiles) { 118 Path targetLocation = filesPath.resolve(additionalFile.getOriginalFilename()); 119 120 try { 121 Files.createDirectories(filesPath); 122 Files.copy(additionalFile.getInputStream(), targetLocation); 123 } catch (IOException e) { 124 throw new RuntimeException(e); 125 } 126 127 String relativePath = Paths.get("uploads","applications",String.valueOf(application.getId()), 128 "additional_files", additionalFile.getOriginalFilename()).toString(); 129 List<String> currentAdditionalFilePaths = application.getAdditionalFilePaths(); 130 currentAdditionalFilePaths.add(relativePath); 131 application.setAdditionalFilePaths(currentAdditionalFilePaths); 132 application = applicationRepository.save(application); 133 } 134 return Application.mapToApplicationDetailsDTO(application); 135 } 136 137 @Override 97 138 public List<ApplicationDetailsDTO> findAllByJobAdvertisementId(Long jobId) { 98 139 List<Application> applications = applicationRepository.findAllByJobAdvertisementId(jobId); … … 101 142 102 143 @Override 144 public List<ApplicationDetailsDTO> filterByJobAdvertisementId(Long jobId, String status) { 145 List<Application> applications = applicationRepository.findAllByJobAdvertisementId(jobId); 146 String statusTrimmed = status.subSequence(0, status.length()-1).toString(); 147 148 if(statusTrimmed.equals("ALL")) { 149 applications = applicationRepository.findAllByJobAdvertisementId(jobId); 150 } else { 151 applications = applications.stream().filter(application -> application.getStatus().name().equals(statusTrimmed)).toList(); 152 } 153 return applications.stream().map(Application::mapToApplicationDetailsDTO).toList(); 154 } 155 156 @Override 103 157 public List<ApplicationDetailsDTO> findAllByJobSeekerId(Long jobSeekerId) { 104 158 List<Application> applications = applicationRepository.findAllByJobSeekerId(jobSeekerId); 105 159 return applications.stream().map(Application::mapToApplicationDetailsDTO).toList(); 160 } 161 162 @Override 163 public List<ApplicationDetailsDTO> filterByJobSeekerId(Long jobSeekerId, String status) { 164 List<Application> applications = applicationRepository.findAllByJobSeekerId(jobSeekerId); 165 String statusTrimmed = status.subSequence(0, status.length()-1).toString(); 166 if(statusTrimmed.equals("ALL")) { 167 applications = applicationRepository.findAllByJobSeekerId(jobSeekerId); 168 } else { 169 applications = applications.stream().filter(application -> application.getStatus().name().equals(statusTrimmed)).toList(); 170 } 171 return applications.stream().map(Application::mapToApplicationDetailsDTO).toList(); 106 172 } 107 173 … … 126 192 } 127 193 194 public List<String> loadAdditionalFilesAsUrls(Long applicationId) { 195 Application application = applicationRepository.findById(applicationId) 196 .orElseThrow(() -> new IllegalArgumentException("Application not found")); 197 198 List<String> fileUrls = new ArrayList<>(); 199 List<String> relativeFilePaths = application.getAdditionalFilePaths(); 200 201 for (String relativeFilePath : relativeFilePaths) { 202 //TO DO: refactor 203 Path filePath = Paths.get(fileStorageLocation.getParent().getParent().toString(), relativeFilePath).normalize(); 204 String relativePath = filePath.toString().replace("\\", "/").replaceFirst("^.+uploads", "uploads"); 205 206 String fileUrl = ServletUriComponentsBuilder.fromCurrentContextPath() 207 .path("/") 208 .path(relativePath) 209 .toUriString(); 210 fileUrls.add(fileUrl); 211 } 212 213 return fileUrls; 214 } 215 216 /* @Override 217 public List<Resource> loadAdditionalFilesAsZippedResource(Long applicationId) { 218 Application application = applicationRepository.findById(applicationId). 219 orElseThrow(() -> new IllegalArgumentException("Application not found")); 220 221 List<Resource> resources = new ArrayList<>(); 222 223 List<String> relativeFilePaths = application.getAdditionalFilePaths(); 224 for(String relativeFilePath: relativeFilePaths) { 225 Path filePath = fileStorageLocation.getParent().getParent().resolve(relativeFilePath).normalize(); 226 227 try { 228 Resource resource = new UrlResource(filePath.toUri()); 229 if (resource.exists()) { 230 resources.add(resource); 231 } 232 } catch (MalformedURLException e) { 233 throw new RuntimeException(e); 234 } 235 } 236 return resources; 237 }*/ 238 239 @Override 240 public List<ApplicationStatusDTO> updateApplications(List<ApplicationStatusDTO> updates) { 241 List<ApplicationStatusDTO> updatedApplications = new ArrayList<>(); 242 243 for(ApplicationStatusDTO applicationStatusDTO : updates) { 244 Application application = applicationRepository.findById(applicationStatusDTO.getId()).orElse(null); 245 if(application != null) { 246 application.setStatus(ApplicationStatus.valueOf(applicationStatusDTO.getStatus())); 247 application.setResponse(applicationStatusDTO.getResponse()); 248 applicationRepository.save(application); 249 updatedApplications.add(applicationStatusDTO); 250 251 //email notification 252 String email = application.getJobSeeker().getEmail(); 253 String subject = application.getJobAdvertisement().getRecruiter().getName() + ": " + application.getJobAdvertisement().getTitle() + " - STATUS UPDATE"; 254 String text = "Dear " + application.getJobSeeker().getName() + ",\n\n"; 255 256 switch (applicationStatusDTO.getStatus()) { 257 case "ACCEPTED": 258 text += "Great news! Your application has been accepted.\n\n"; 259 break; 260 case "DENIED": 261 text += "We regret to inform you that your application has been denied. We appreciate your interest and effort.\n\n"; 262 break; 263 case "PROPOSED": 264 text += "Your application status has been updated to 'Proposed'. We're considering your application for the next phase.\n\n"; 265 break; 266 case "UNDER_REVIEW": 267 text += "Your application is currently under review.\n\n"; 268 break; 269 } 270 271 272 if(!applicationStatusDTO.getResponse().isEmpty()) { 273 text += "Response: " + applicationStatusDTO.getResponse() + "\n\n"; 274 } 275 text += "Thank you."; 276 emailSenderService.sendEmail(email, subject, text); 277 } 278 } 279 return updatedApplications; 280 } 281 128 282 @Override 129 283 public ApplicationStatusDTO updateApplicationStatus(Long id, String status) { … … 132 286 application.setStatus(ApplicationStatus.valueOf(status)); 133 287 applicationRepository.save(application); 134 return new ApplicationStatusDTO(id, status );288 return new ApplicationStatusDTO(id, status, ""); 135 289 } 136 290 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/AuthServiceImpl.java
r0f0add0 r4d97b63 1 1 package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.impl; 2 2 3 import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; 4 import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; 5 import com.google.api.client.http.javanet.NetHttpTransport; 6 import com.google.api.client.json.jackson2.JacksonFactory; 3 7 import lombok.RequiredArgsConstructor; 8 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.config.GoogleOAuth2Properties; 9 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.controllers.AuthController; 10 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.enumerations.Role; 4 11 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.DTO.SignInDTO; 5 12 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.DTO.JwtAuthResponse; … … 12 19 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.UserRepository; 13 20 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.AuthService; 21 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.JobSeekerService; 14 22 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.JwtService; 15 23 import org.springframework.security.authentication.AuthenticationManager; 16 24 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 25 import org.springframework.security.core.authority.SimpleGrantedAuthority; 17 26 import org.springframework.security.crypto.password.PasswordEncoder; 27 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; 28 import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; 29 import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; 30 import org.springframework.security.oauth2.core.user.DefaultOAuth2User; 31 import org.springframework.security.oauth2.core.user.OAuth2User; 18 32 import org.springframework.stereotype.Service; 19 33 import org.springframework.web.multipart.MultipartFile; 34 35 import javax.imageio.ImageIO; 36 import java.awt.image.BufferedImage; 37 import java.io.ByteArrayInputStream; 38 import java.io.ByteArrayOutputStream; 39 import java.io.IOException; 40 import java.io.InputStream; 41 import java.net.URL; 20 42 import java.time.LocalDateTime; 43 import java.util.Collections; 21 44 import java.util.HashMap; 45 import java.util.Map; 46 import java.util.Optional; 22 47 23 48 @Service … … 30 55 private final AuthenticationManager authenticationManager; 31 56 private final UserRepository userRepository; 57 private final JobSeekerService jobSeekerService; 32 58 private final JwtService jwtService; 59 private final GoogleOAuth2Properties googleOAuth2Properties; 33 60 34 61 @Override … … 56 83 return new JwtAuthResponse(user.getId(), user.getEmail(), user.getName(), user.getRole().name(), user.isHasAccess(), jwt, refreshJwt); 57 84 } 58 85 59 86 public JwtAuthResponse refreshToken(RefreshTokenRequest refreshTokenRequest) { 60 87 String userEmail = jwtService.extractUsername(refreshTokenRequest.getToken()); 61 88 User user = userRepository.findByEmail(userEmail).orElseThrow(); 62 if (jwtService.isTokenValid(refreshTokenRequest.getToken(), user)) {89 if (jwtService.isTokenValid(refreshTokenRequest.getToken(), user)) { 63 90 String jwt = jwtService.generateToken(user); 64 91 … … 67 94 return null; 68 95 } 96 97 @Override 98 public JwtAuthResponse googleSignIn(Map<String, String> token) { 99 OAuth2AuthenticationToken authentication = getAuthentication(token.get("tokenId")); 100 101 OAuth2User oAuth2User = authentication.getPrincipal(); 102 String email = oAuth2User.getAttribute("email"); 103 104 JobSeeker jobSeeker = jobSeekerRepository.findByEmail(email) 105 .orElseGet(() -> { 106 JobSeeker newJobSeeker = new JobSeeker(); 107 newJobSeeker.setEmail(email); 108 newJobSeeker.setFirstName(oAuth2User.getAttribute("given_name")); 109 newJobSeeker.setLastName(oAuth2User.getAttribute("family_name")); 110 newJobSeeker.setPassword(""); 111 newJobSeeker.setRole(Role.ROLE_JOBSEEKER); 112 newJobSeeker.setHasAccess(true); 113 jobSeekerRepository.save(newJobSeeker); 114 115 String googleProfilePicUrl = oAuth2User.getAttribute("picture"); 116 submitGoogleProfilePic(newJobSeeker.getId(), googleProfilePicUrl); 117 118 return newJobSeeker; 119 }); 120 121 String jwt = jwtService.generateToken(jobSeeker); 122 123 return new JwtAuthResponse( 124 jobSeeker.getId(), 125 jobSeeker.getEmail(), 126 jobSeeker.getFirstName() + " " + jobSeeker.getLastName(), 127 jobSeeker.getRole().name(), 128 jobSeeker.isHasAccess(), 129 jwt, 130 null 131 ); 132 } 133 134 public OAuth2AuthenticationToken getAuthentication(String tokenId) { 135 try { 136 GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new JacksonFactory()) 137 .setAudience(Collections.singletonList(googleOAuth2Properties.getClientId())) 138 .build(); 139 140 GoogleIdToken idToken = verifier.verify(tokenId); 141 if (idToken != null) { 142 GoogleIdToken.Payload payload = idToken.getPayload(); 143 144 String userId = payload.getSubject(); 145 String email = payload.getEmail(); 146 boolean emailVerified = Boolean.TRUE.equals(payload.getEmailVerified()); 147 String name = (String) payload.get("name"); 148 String pictureUrl = (String) payload.get("picture"); 149 String familyName = Optional.ofNullable((String) payload.get("family_name")).orElse(""); 150 String givenName = (String) payload.get("given_name"); 151 152 Map<String, Object> attributes = Map.of( 153 "sub", userId, 154 "email", email, 155 "email_verified", emailVerified, 156 "name", name, 157 "picture", pictureUrl, 158 "family_name", familyName, 159 "given_name", givenName 160 ); 161 162 OAuth2User oAuth2User = new DefaultOAuth2User( 163 Collections.singleton(new SimpleGrantedAuthority("ROLE_JOBSEEKER")), 164 attributes, 165 "sub" 166 ); 167 168 return new OAuth2AuthenticationToken(oAuth2User, oAuth2User.getAuthorities(), "google"); 169 } else { 170 throw new IllegalArgumentException("Invalid ID token"); 171 } 172 } catch (Exception e) { 173 throw new RuntimeException("Failed to verify token", e); 174 } 175 } 176 177 public void submitGoogleProfilePic(Long jobSeekerId, String googleProfilePicUrl) { 178 try { 179 URL url = new URL(googleProfilePicUrl); 180 BufferedImage image = ImageIO.read(url); 181 182 // Convert BufferedImage to byte array 183 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 184 ImageIO.write(image, "jpg", baos); 185 byte[] imageBytes = baos.toByteArray(); 186 187 // Convert byte array to MultipartFile 188 MultipartFile multipartFile = new InMemoryMultipartFile("profilePicFile", "google-profile-pic.jpg", "image/jpeg", imageBytes); 189 190 jobSeekerService.submitProfilePic(jobSeekerId, multipartFile); 191 } catch (IOException e) { 192 e.printStackTrace(); 193 } 194 } 195 196 class InMemoryMultipartFile implements MultipartFile { 197 198 private final String name; 199 private final String originalFilename; 200 private final String contentType; 201 private final byte[] content; 202 203 public InMemoryMultipartFile(String name, String originalFilename, String contentType, byte[] content) { 204 this.name = name; 205 this.originalFilename = originalFilename; 206 this.contentType = contentType; 207 this.content = content; 208 } 209 210 @Override 211 public String getName() { 212 return name; 213 } 214 215 @Override 216 public String getOriginalFilename() { 217 return originalFilename; 218 } 219 220 @Override 221 public String getContentType() { 222 return contentType; 223 } 224 225 @Override 226 public boolean isEmpty() { 227 return content.length == 0; 228 } 229 230 @Override 231 public long getSize() { 232 return content.length; 233 } 234 235 @Override 236 public byte[] getBytes() throws IOException { 237 return content; 238 } 239 240 @Override 241 public InputStream getInputStream() throws IOException { 242 return new ByteArrayInputStream(content); 243 } 244 245 @Override 246 public void transferTo(java.io.File dest) throws IOException { 247 throw new UnsupportedOperationException("This method is not implemented"); 248 } 249 } 69 250 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/ApplicationService.java
r0f0add0 r4d97b63 7 7 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationStatusDTO; 8 8 import org.springframework.core.io.Resource; 9 import org.springframework.web.multipart.MultipartFile; 9 10 10 11 import java.util.List; … … 12 13 public interface ApplicationService { 13 14 ApplicationDetailsDTO submitApplication(ApplicationDTO applicationDTO); 15 ApplicationDetailsDTO updateApplication(Long applicationId, MultipartFile[] additionalFiles); 14 16 List<ApplicationDetailsDTO> findAllByJobAdvertisementId(Long jobId); 17 List<ApplicationDetailsDTO> filterByJobAdvertisementId(Long jobId, String status); 15 18 List<ApplicationDetailsDTO> findAllByJobSeekerId(Long jobSeekerId); 19 List<ApplicationDetailsDTO> filterByJobSeekerId(Long jobSeekerId, String status); 16 20 Resource loadResumeAsResource(Long applicationId); 21 List<String> loadAdditionalFilesAsUrls(Long applicationId); 17 22 ApplicationStatusDTO updateApplicationStatus(Long id, String status); 23 List<ApplicationStatusDTO> updateApplications(List<ApplicationStatusDTO> updates); 18 24 } -
jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/AuthService.java
r0f0add0 r4d97b63 7 7 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.Recruiter; 8 8 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User; 9 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; 10 11 import java.util.Map; 9 12 10 13 public interface AuthService { … … 13 16 JwtAuthResponse signIn(SignInDTO signInDTO); 14 17 JwtAuthResponse refreshToken(RefreshTokenRequest refreshTokenRequest); 18 19 JwtAuthResponse googleSignIn(Map<String, String> token); 20 OAuth2AuthenticationToken getAuthentication(String tokenId); 21 void submitGoogleProfilePic(Long jobSeekerId, String googleProfilePicUrl); 15 22 }
Note:
See TracChangeset
for help on using the changeset viewer.