Skip to content

Commit

Permalink
Merge pull request #176 from PawWithU/feat/173-change-password-api
Browse files Browse the repository at this point in the history
[Feature] 비밀번호 찾기 - 이동봉사자, 모집자 비밀번호 변경 API 구현
  • Loading branch information
kyeong-hyeok authored May 5, 2024
2 parents 4dd88eb + 5745b86 commit 8e5371a
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.pawwithu.connectdog.domain.intermediary.controller;

import com.pawwithu.connectdog.domain.intermediary.dto.request.IntermediaryMyProfileRequest;
import com.pawwithu.connectdog.domain.intermediary.dto.request.IntermediaryPasswordRequest;
import com.pawwithu.connectdog.domain.intermediary.dto.response.*;
import com.pawwithu.connectdog.domain.intermediary.service.IntermediaryService;
import com.pawwithu.connectdog.error.dto.ErrorResponse;
Expand Down Expand Up @@ -139,4 +140,16 @@ public ResponseEntity<Void> intermediaryMyProfile(@AuthenticationPrincipal UserD
return ResponseEntity.noContent().build();
}

@Operation(summary = "비밀번호 찾기 - 모집자 비밀번호 변경", description = "모집자 비밀번호를 변경합니다.",
responses = {@ApiResponse(responseCode = "204", description = "비밀번호 변경 성공")
, @ApiResponse(responseCode = "400"
, description = "M2, 해당 이동봉사 중개를 찾을 수 없습니다. \t\n V1, 영문+숫자 10자 이상 또는 영문+숫자+특수기호 8자 이상을 입력해 주세요."
, content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@PatchMapping("/intermediaries/password")
public ResponseEntity<Void> changePassword(@AuthenticationPrincipal UserDetails loginUser, @RequestBody IntermediaryPasswordRequest request) {
intermediaryService.changePassword(loginUser.getUsername(), request.password());
return ResponseEntity.noContent().build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.pawwithu.connectdog.domain.intermediary.dto.request;

import jakarta.validation.constraints.Pattern;

public record IntermediaryPasswordRequest(@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d).{10,}$|^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[~!@#$%^&*()+|=?]).{8,}$",
message = "영문+숫자 10자 이상 또는 영문+숫자+특수기호 8자 이상을 입력해 주세요.")
String password) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,8 @@ public void updateProfileWithoutImage(String intro, String contact, String guide
this.contact = contact;
this.guide = guide;
}

public void updatePassword(String password) {
this.password = password;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -34,6 +35,7 @@ public class IntermediaryService {
private final CustomReviewRepository customReviewRepository;
private final CustomDogStatusRepository customDogStatusRepository;
private final FileService fileService;
private final PasswordEncoder passwordEncoder;

@Transactional(readOnly = true)
public List<IntermediaryGetPostsResponse> volunteerGetIntermediaryPosts(Long intermediaryId, String orderCondition, Pageable pageable) {
Expand Down Expand Up @@ -147,4 +149,10 @@ public List<IntermediaryGetPostsResponse> intermediaryGetIntermediaryPosts(Strin
List<IntermediaryGetPostsResponse> intermediaryPosts = customPostRepository.getIntermediaryPosts(intermediary.getId(), orderCondition, pageable);
return intermediaryPosts;
}

public void changePassword(String email, String password) {
Intermediary intermediary = intermediaryRepository.findByEmail(email).orElseThrow(() -> new BadRequestException(INTERMEDIARY_NOT_FOUND));
intermediary.updatePassword(password);
intermediary.passwordEncode(passwordEncoder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.pawwithu.connectdog.domain.volunteer.dto.request.AdditionalAuthRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.request.NicknameRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.request.VolunteerMyProfileRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.request.VolunteerPasswordRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.response.*;
import com.pawwithu.connectdog.domain.volunteer.service.VolunteerService;
import com.pawwithu.connectdog.error.dto.ErrorResponse;
Expand Down Expand Up @@ -113,4 +114,16 @@ public ResponseEntity<VolunteerGetProfileResponse> getMyProfile(@AuthenticationP
return ResponseEntity.ok(response);
}

@Operation(summary = "비밀번호 찾기 - 이동봉사자 비밀번호 변경", description = "이동봉사자 비밀번호를 변경합니다.",
responses = {@ApiResponse(responseCode = "204", description = "비밀번호 변경 성공")
, @ApiResponse(responseCode = "400"
, description = "M1, 해당 이동봉사자를 찾을 수 없습니다. \t\n V1, 영문+숫자 10자 이상 또는 영문+숫자+특수기호 8자 이상을 입력해 주세요."
, content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@PatchMapping("/password")
public ResponseEntity<Void> changePassword(@AuthenticationPrincipal UserDetails loginUser, @RequestBody VolunteerPasswordRequest request) {
volunteerService.changePassword(loginUser.getUsername(), request.password());
return ResponseEntity.noContent().build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.pawwithu.connectdog.domain.volunteer.dto.request;

import jakarta.validation.constraints.Pattern;

public record VolunteerPasswordRequest(@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d).{10,}$|^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[~!@#$%^&*()+|=?]).{8,}$",
message = "영문+숫자 10자 이상 또는 영문+숫자+특수기호 8자 이상을 입력해 주세요.")
String password) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,8 @@ public void updateMyProfile(String nickname, Integer profileImageNum) {
public void updateProfileImage(Integer profileImageNum) {
this.profileImageNum = profileImageNum;
}

public void updatePassword(String password) {
this.password = password;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.pawwithu.connectdog.error.exception.custom.BadRequestException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -35,6 +36,7 @@ public class VolunteerService {
private final CustomDogStatusRepository customDogStatusRepository;
private final CustomBookmarkRepository customBookmarkRepository;
private final CustomVolunteerBadgeRepository customVolunteerBadgeRepository;
private final PasswordEncoder passwordEncoder;

@Transactional(readOnly = true)
public NicknameResponse isNicknameDuplicated(NicknameRequest nickNameRequest) {
Expand Down Expand Up @@ -104,4 +106,10 @@ public VolunteerGetProfileResponse getMyProfile(String email) {
VolunteerGetProfileResponse profile = VolunteerGetProfileResponse.of(volunteer.getProfileImageNum(), volunteer.getNickname());
return profile;
}

public void changePassword(String email, String password) {
Volunteer volunteer = volunteerRepository.findByEmail(email).orElseThrow(() -> new BadRequestException(VOLUNTEER_NOT_FOUND));
volunteer.updatePassword(password);
volunteer.passwordEncode(passwordEncoder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pawwithu.connectdog.domain.dog.entity.DogSize;
import com.pawwithu.connectdog.domain.intermediary.dto.request.IntermediaryMyProfileRequest;
import com.pawwithu.connectdog.domain.intermediary.dto.request.IntermediaryPasswordRequest;
import com.pawwithu.connectdog.domain.intermediary.dto.response.*;
import com.pawwithu.connectdog.domain.intermediary.service.IntermediaryService;
import com.pawwithu.connectdog.utils.TestUserArgumentResolver;
Expand Down Expand Up @@ -262,4 +263,22 @@ void setUp() {
result.andExpect(status().isNoContent());
verify(intermediaryService, times(1)).intermediaryMyProfile(anyString(), any(), any());
}

@Test
void 비밀번호_찾기_모집자_비밀번호_변경() throws Exception {
// given
IntermediaryPasswordRequest request = new IntermediaryPasswordRequest("dkssudgktpdy!");

// when
ResultActions result = mockMvc.perform(
patch("/intermediaries/password")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request))
);

// then
result.andExpect(status().isNoContent());
verify(intermediaryService, times(1)).changePassword(anyString(), any());

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.pawwithu.connectdog.domain.volunteer.dto.request.AdditionalAuthRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.request.NicknameRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.request.VolunteerMyProfileRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.request.VolunteerPasswordRequest;
import com.pawwithu.connectdog.domain.volunteer.dto.response.*;
import com.pawwithu.connectdog.domain.volunteer.service.VolunteerService;
import com.pawwithu.connectdog.utils.TestUserArgumentResolver;
Expand Down Expand Up @@ -177,4 +178,22 @@ void setUp() {
result.andExpect(status().isOk());
verify(volunteerService, times(1)).getMyProfile(anyString());
}

@Test
void 비밀번호_찾기_이동봉사자_비밀번호_변경() throws Exception {
// given
VolunteerPasswordRequest request = new VolunteerPasswordRequest("dkssudgktpdy!");

// when
ResultActions result = mockMvc.perform(
patch("/volunteers/password")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request))
);

// then
result.andExpect(status().isNoContent());
verify(volunteerService, times(1)).changePassword(anyString(), any());

}
}

0 comments on commit 8e5371a

Please sign in to comment.