-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[STEP2-4] Add Feature Blocking domains #113
base: sunsun512
Are you sure you want to change the base?
Changes from all commits
2e31eae
ff516b8
c1c7ef5
be71eb0
747da5d
7404917
0415173
45428dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package community.whatever.onembackendjava.api.controller; | ||
|
||
import community.whatever.onembackendjava.api.service.CsvReaderService; | ||
import community.whatever.onembackendjava.common.util.ResponseFormatter; | ||
import community.whatever.onembackendjava.common.util.model.ResultJson; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/csv") | ||
public class CsvController { | ||
|
||
private final CsvReaderService csvReaderService; | ||
|
||
|
||
// CSV 파일을 업로드하여 차단 도메인 목록 갱신 | ||
@PostMapping("/upload") | ||
public ResponseEntity<ResultJson> uploadCsv(@RequestPart(name = "blockDomains") MultipartFile file) { | ||
log.info("file >> {}", file); | ||
csvReaderService.loadBlockedDomains(file); | ||
return ResponseFormatter.ConvertResponse(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package community.whatever.onembackendjava.api.domain; | ||
|
||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import java.util.Set; | ||
|
||
public interface BlockedDomainInterface { | ||
void loadBlockedDomains(MultipartFile file); // CSV 파일에서 차단 목록 로드 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fyi. javadoc |
||
Set<String> getBlockedDomains(); // 차단된 도메인 목록 반환 | ||
boolean isBlocked(String url); // 특정 URL이 차단된 도메인인지 확인 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package community.whatever.onembackendjava.api.service; | ||
|
||
import community.whatever.onembackendjava.api.domain.BlockedDomainInterface; | ||
import community.whatever.onembackendjava.common.error.BusinessExceptionGenerator; | ||
import community.whatever.onembackendjava.common.error.model.ErrorCode; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.InputStreamReader; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
|
||
@Slf4j | ||
@Service | ||
public class CsvReaderService implements BlockedDomainInterface { | ||
|
||
private Set<String> blockedDomains = new HashSet<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fyi. 일급 컬렉션, holder |
||
|
||
// CSV 파일을 읽어 BlockedDomains 리스트에 저장 | ||
public void loadBlockedDomains(MultipartFile file) { | ||
if (file.isEmpty()) throw BusinessExceptionGenerator.createBusinessException(ErrorCode.DB001); | ||
|
||
Set<String> domainSet = new HashSet<>(); | ||
try (BufferedReader br = new BufferedReader( | ||
new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) { | ||
|
||
String line; | ||
while ((line = br.readLine()) != null) { | ||
domainSet.add(line.trim()); | ||
} | ||
Comment on lines
+31
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blockedDomains.addAll(br.lines()
.map(String::trim)
.collect(Collectors.toSet()));
|
||
} catch (Exception e) { | ||
throw BusinessExceptionGenerator.createBusinessException("RU001", e.getMessage()); | ||
} | ||
|
||
this.blockedDomains = domainSet; // 새로운 데이터로 업데이트 | ||
} | ||
|
||
// 차단된 도메인 목록 반환 | ||
public Set<String> getBlockedDomains() { | ||
return blockedDomains; | ||
} | ||
|
||
// URL이 차단된 도메인에 포함되는지 확인 | ||
public boolean isBlocked(String url) { | ||
for (String domain : blockedDomains) { | ||
if (url.contains(domain)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
Comment on lines
+48
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. public boolean isBlocked(String url) {
return blockedDomains.stream().anyMatch(url::contains);
}
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,34 @@ | ||
package community.whatever.onembackendjava.api.service; | ||
|
||
import community.whatever.onembackendjava.api.domain.BlockedDomainInterface; | ||
import community.whatever.onembackendjava.api.dto.ShortenUrlDto; | ||
import community.whatever.onembackendjava.common.error.BusinessException; | ||
import community.whatever.onembackendjava.common.error.BusinessExceptionGenerator; | ||
import community.whatever.onembackendjava.common.error.model.ErrorCode; | ||
import community.whatever.onembackendjava.common.util.BlackListService; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.util.StringUtils; | ||
|
||
import java.util.*; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Stream; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class UrlShortenService { | ||
|
||
private final BlockedDomainInterface blockedDomainInterface; | ||
private static final String UrlRegex = "https?://(?:www\\.)?[a-zA-Z0-9./]+"; | ||
private static final Pattern URL_PATTERN = Pattern.compile(UrlRegex); | ||
|
||
private final Map<String, String> shortenUrls = new HashMap<>(); | ||
|
||
public ShortenUrlDto.Get.Response shortenUrlSearch(ShortenUrlDto.Get.Request param){ | ||
if (!shortenUrls.containsKey(param.getKey())) { | ||
throw BusinessExceptionGenerator.createBusinessException("DB003"); | ||
throw BusinessExceptionGenerator.createBusinessException(ErrorCode.DB003); | ||
} | ||
|
||
return ShortenUrlDto.Get.Response.builder() | ||
|
@@ -33,7 +38,10 @@ public ShortenUrlDto.Get.Response shortenUrlSearch(ShortenUrlDto.Get.Request par | |
|
||
public ShortenUrlDto.Create.Response shortenUrlCreate(ShortenUrlDto.Create.Request param){ | ||
if (validateOriginUrl(param.getOriginUrl())) { | ||
throw BusinessExceptionGenerator.createBusinessException("DB001"); | ||
throw BusinessExceptionGenerator.createBusinessException(ErrorCode.DB001); | ||
} | ||
if(blockedDomainInterface.isBlocked(param.getOriginUrl())){ | ||
throw BusinessExceptionGenerator.createBusinessException(ErrorCode.DB004); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런 형식이라면 ErrorCode enum 을 매개변수로 받는게 낫지 않나요? |
||
|
||
Random random = new Random(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package community.whatever.onembackendjava.common.util; | ||
|
||
import org.springframework.core.env.Environment; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
@Component | ||
public class BlackListService { | ||
private final List<String> blockedDomains; | ||
|
||
public BlackListService(Environment env) { | ||
String domains = env.getProperty("spring.blacklist.domains", ""); // 기본값 빈 문자열 | ||
this.blockedDomains = Arrays.stream(domains.split(",")) | ||
.filter(domain -> !domain.isEmpty()) | ||
.toList(); | ||
} | ||
sunsun512 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public List<String> getBlockedDomains() { | ||
return blockedDomains; | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.