diff --git a/.idea/modules.xml b/.idea/modules.xml index b5c8995..a54a58a 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,7 +3,6 @@ - \ No newline at end of file diff --git a/web3-credential-server/build.gradle b/web3-credential-server/build.gradle index ca824f0..cc79e83 100644 --- a/web3-credential-server/build.gradle +++ b/web3-credential-server/build.gradle @@ -51,6 +51,7 @@ dependencies { implementation 'org.springframework.security:spring-security-crypto' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' + implementation 'org.hyperledger.fabric:fabric-gateway-java:2.2.0' } diff --git a/web3-credential-server/src/main/java/web3/controller/Identity/IdentityController.java b/web3-credential-server/src/main/java/web3/controller/Identity/IdentityController.java index 3d10094..c82a76a 100644 --- a/web3-credential-server/src/main/java/web3/controller/Identity/IdentityController.java +++ b/web3-credential-server/src/main/java/web3/controller/Identity/IdentityController.java @@ -1,2 +1,40 @@ -package web3.controller.Identity;public class IdentityController { +package web3.controller.Identity; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import web3.service.Identity.IdentityService; +import web3.service.dto.Identity.StudentCertificationDto; + +@RestController +@RequestMapping("/api/certifications") +public class IdentityController { + + private final IdentityService identityService; + + @Autowired + public IdentityController(IdentityService identityService) { + this.identityService = identityService; + } + + @PostMapping("/register") + public ResponseEntity registerCertification(@RequestBody StudentCertificationDto certificationDto) { + try { + identityService.registerStudentCertification(certificationDto); + return ResponseEntity.ok("재학증이 성공적으로 등록되었습니다."); + } catch (Exception e) { + return ResponseEntity.status(500).body("재학증 등록 중 오류 발생: " + e.getMessage()); + } + } + + @GetMapping("/{key}") + public ResponseEntity getCertification(@PathVariable String key) { + try { + StudentCertificationDto certificationDto = identityService.queryStudentCertification(key); + return ResponseEntity.ok(certificationDto); + } catch (Exception e) { + return ResponseEntity.status(404).body(null); + } + } } + diff --git a/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java b/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java index 90fcc4d..a2fa878 100644 --- a/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java +++ b/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java @@ -1,2 +1,113 @@ -package web3.service.Identity;public class IdentityService { +package web3.service.Identity; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import web3.service.dto.Identity.StudentCertificationDto; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.TimeoutException; + +import org.hyperledger.fabric.gateway.Contract; +import org.hyperledger.fabric.gateway.ContractException; +import org.hyperledger.fabric.gateway.Gateway; +import org.hyperledger.fabric.gateway.Network; +import org.hyperledger.fabric.gateway.Wallet; +import org.hyperledger.fabric.gateway.Wallets; + +@Service +public class IdentityService { + private static final Logger logger = LoggerFactory.getLogger(IdentityService.class); + private Gateway gateway; + private Network network; + + public IdentityService() { + try { + // Wallet 설정 및 connection.yaml 로드 + Path walletPath = Paths.get("wallet"); + Wallet wallet = Wallets.newFileSystemWallet(walletPath); + + // InputStream을 통해 connection.yaml 로드 + InputStream networkConfigStream = new ClassPathResource("connection.yaml").getInputStream(); + + // "admin" ID 확인 + if (wallet.get("admin") == null) { + throw new IllegalArgumentException("Identity 'admin' not found in wallet."); + } + + Gateway.Builder builder = Gateway.createBuilder(); + builder.identity(wallet, "admin").networkConfig(networkConfigStream).discovery(true); + + this.gateway = builder.connect(); + this.network = gateway.getNetwork("mychannel"); + logger.info("블록체인 네트워크에 성공적으로 연결되었습니다."); + } catch (IOException e) { + logger.error("블록체인 네트워크 연결 실패: {}", e.getMessage()); + throw new RuntimeException("블록체인 네트워크 초기화 실패", e); + } + } + + + // 재학증 등록 + public void registerStudentCertification(StudentCertificationDto certificationDto) { + // 블록체인에 저장할 StudentCertification 데이터 형식 생성 + String certificationData = String.format("email:%s/univName:%s/univ_check:%b", + certificationDto.getEmail(), + certificationDto.getUnivName(), + certificationDto.isUnivCheck()); + + // 블록체인에 데이터 저장 + try { + putDataOnBlockchain(certificationDto.getKey(), certificationData); + } catch (ContractException | TimeoutException | InterruptedException e) { + logger.error("체인코드 트랜잭션 제출 중 오류 발생: {}", e.getMessage()); + throw new RuntimeException("블록체인에 데이터 등록 실패", e); // 언체크 예외 + } + } + + // 재학증 조회 + public StudentCertificationDto queryStudentCertification(String key) { + // 블록체인에서 데이터 조회 + String data; + try { + data = getDataFromBlockchain(key); + } catch (ContractException | TimeoutException e) { + logger.error("체인코드 데이터 조회 중 오류 발생: {}", e.getMessage()); + throw new RuntimeException("블록체인 데이터 조회 실패", e); // 언체크 예외 + } + + if (data == null) { + throw new IllegalArgumentException("재학증이 발견되지 않았습니다."); // 언체크 예외 + } + + // 데이터 파싱 + String[] parts = data.split("/"); + String email = parts[0].split(":")[1]; + String univName = parts[1].split(":")[1]; + boolean univCheck = Boolean.parseBoolean(parts[2].split(":")[1]); + + return new StudentCertificationDto(key, email, univName, univCheck); + } + + private void putDataOnBlockchain(String key, String data) throws ContractException, TimeoutException, InterruptedException { + submitTransaction("putData", key, data); + } + + private String getDataFromBlockchain(String key) throws ContractException, TimeoutException { + return evaluateTransaction("getData", key); + } + + private void submitTransaction(String functionName, String... args) throws ContractException, TimeoutException, InterruptedException { + byte[] result = this.network.getContract("certification").submitTransaction(functionName, args); + logger.info("트랜잭션이 제출되었습니다: " + new String(result)); + } + + private String evaluateTransaction(String functionName, String... args) throws ContractException, TimeoutException { + byte[] result = this.network.getContract("certification").evaluateTransaction(functionName, args); + return new String(result); + } } diff --git a/web3-credential-server/src/main/java/web3/service/cert/UnivCertService.java b/web3-credential-server/src/main/java/web3/service/cert/UnivCertService.java index 3b05899..5aa2296 100644 --- a/web3-credential-server/src/main/java/web3/service/cert/UnivCertService.java +++ b/web3-credential-server/src/main/java/web3/service/cert/UnivCertService.java @@ -29,6 +29,8 @@ public Mono sendCertificationRequest(String email, String univName) { } // 인증 코드 검증 메서드 + // 검증 완료되면 사용자 초기화 후 지갑 생성 후 지갑 id를 포함해서 재학증_walletId_0을 저장한다 + // 재학증을 새로 등록 할때마다 -> 재학증_walletId_0 -> 재학증_walletId_1 -> 재학증_walletId_2 처럼 +1씩 증가되어서 블록에 키로 저장됨 public Mono verifyCertificationCode(String email, String univName, int code) { String jsonRequest = "{\n" + " \"key\": \"" + CERT_KEY + "\",\n" + diff --git a/web3-credential-server/src/main/java/web3/service/dto/Identity/StudentCertificationDto.java b/web3-credential-server/src/main/java/web3/service/dto/Identity/StudentCertificationDto.java index 83a629a..d5ef2d1 100644 --- a/web3-credential-server/src/main/java/web3/service/dto/Identity/StudentCertificationDto.java +++ b/web3-credential-server/src/main/java/web3/service/dto/Identity/StudentCertificationDto.java @@ -1,2 +1,48 @@ -package web3.service.dto.Identity;public class StudentCertificationDto { +package web3.service.dto.Identity; + +public class StudentCertificationDto { + private String key; //재학증_walletId + private String email; + private String univName; + private boolean univCheck; + + public StudentCertificationDto(String key, String email, String univName, boolean univCheck) { + this.key = key; + this.email = email; + this.univName = univName; + this.univCheck = univCheck; + } + + // Getters and Setters + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getUnivName() { + return univName; + } + + public void setUnivName(String univName) { + this.univName = univName; + } + + public boolean isUnivCheck() { + return univCheck; + } + + public void setUnivCheck(boolean univCheck) { + this.univCheck = univCheck; + } }