Skip to content

Commit

Permalink
Merge pull request #4 from aemini/url-config
Browse files Browse the repository at this point in the history
Url config
  • Loading branch information
aemini authored Oct 13, 2024
2 parents 7a9ab9e + ce33c20 commit 9050d11
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 14 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.aryaemini.nvi</groupId>
<artifactId>tckno-validator</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
<packaging>jar</packaging>

<name>T.C. Kimlik Dogrulama</name>
Expand Down
62 changes: 60 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Ad, soyad, doğum yılı ve T.C. kimlik numarası girdilerinin geçerliliğini N
<dependency>
<groupId>com.aryaemini.nvi</groupId>
<artifactId>tckno-validator</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</dependency>

## 2. Kullanım
Expand Down Expand Up @@ -55,7 +55,65 @@ try {
}
```

## 4. Değişiklikler
## 3. Ayarlar

NVİ servislerinin adresinin değişme ihtimaline karşı url'lerin parametrik olması konusunda ricada bulunulması üzerine bu bölüm açıldı.
Kütüphane, herhangi bir konfigürasyon ihtiyacı olmadan çalışmaktadır, herhangi bir url tanımı yapılması gerekmemektedir.

Kütüphane yaşam döngüsüne başlarken öncelikle konfigürasyon dosyasına bakar (`System.getProperty()`). Bu, Spring Framework için `application.properties` veya `application.yaml` dosyasıdır.
Eğer başka bir çatı kullanıyorsanız ayarları sakladığınız dosyaya nitelikleri anahtar değer ikilisi olarak ekleyebilirsiniz.
Konfigürasyon dosyasında aşağıda tablodaki nitelikleri bulamazsa ortam değişkenkeri tablosundaki değerlere bakar.
Burada da herhangi bir tanım yoksa varsayılan değerlerle singleton olarak çalışır.

##### Örnek yaml
```yaml
...
com:
aryaemini:
nvi:
url:
identity-card: https://tckimlik.nvi.gov.tr/Service/KPSPublicV2.asmx
person: https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx
...
```
##### Örnek properties
```properties
####################### T.C. Kimlik Kontrolu #######################
com.aryaemini.nvi.url.identity-card: https://tckimlik.nvi.gov.tr/Service/KPSPublicV2.asmx
com.aryaemini.nvi.url.person: https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx
####################### T.C. Kimlik Kontrolu #######################
```

#### Nitelikler

| Nitelik | Tip | Varsayılan Değer |
|:------------------------------------|:-------|:-----------------------------------------------------|
| com.aryaemini.nvi.url.identity-card | String | https://tckimlik.nvi.gov.tr/Service/KPSPublicV2.asmx |
| com.aryaemini.nvi.url.person | String | https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx |

#### Ortam Değişkenleri
| Değişken | Tip |
|:--------------------------------------------|:-------|
| TCKN_VALIDATOR_IDENTITY_CARD_VALIDATION_URL | String |
| TCKN_VALIDATOR_PERSON_VALIDATION_URL | String |

## 4. KVKK Uyarısı
> [!IMPORTANT]
> Bu kütüphane, T.C. Kimlik Numarası doğrulama işlemleri için kullanılırken herhangi bir kişisel veri saklamaz veya depolamaz.
> Ancak, kütüphaneyi kullanan kişiler, Türkiye Cumhuriyeti Kanunları çerçevesinde "Veri Sorumlusu" olarak kabul edilebilir ve **6698 sayılı Kişisel Verilerin Korunması Kanunu (KVKK)** gerekliliklerine uymakla yükümlüdür. Lütfen kişisel veri işlemlerinde gerekli yasal düzenlemelere dikkat ediniz.
> [!CAUTION]
> Eğer `com.aryaemini.nvi.*` paketi `debug` (`fine`) veya daha düşük seviyede (`trace` | `finest`) loglanırsa hassas bilgiler de log kanalına iletilir.
>
> URL değişim özelliği; yalnızca servis adresinin değişmesi ihtimalinde, geliştirme ve onaylanma sürecini beklemeden acil değişim imkanı sağlaması maksadıyla eklenmiştir. URL değişim özelliği veya hata ayıklama modunu kullanırken log kanalına aktarılan veya güvensiz bir URL'ye iletilen bu tür bilgilerin güvenliğinden ve korunmasından tamamen "**VERİ SORUMLUSU**" sıfatıyla kütüphaneyi kullanan kişi veya kurum sorumludur.
>
> **6698 sayılı Kişisel Verilerin Korunması Kanunu** (KVKK) çerçevesinde, bu bilgilerin korunmasına yönelik gerekli tedbirlerin alınması yasal zorunluluktur. **Hata ayıklama modunu yalnızca güvenli bir ortamda kullanmanızı öneririz.**

## 5. Değişiklikler

### 1.5.2)
Servis URL'sinin değiştirilebilmesi için gereken ayarlar yapıldı. Kullanımda değişiklik yok.

### 1.5.1)
Yalnızca kod optimizasyonu yapıldı. Kullanımda bir değişiklik olmadı.
Expand Down
88 changes: 77 additions & 11 deletions src/main/java/com/aryaemini/nvi/TCKNoValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@
import jakarta.xml.soap.SOAPPart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

public class TCKNoValidator {
Expand All @@ -25,16 +30,26 @@ public class TCKNoValidator {
private static final String MESSAGE_EMPTY_FIELD = "Doldurulmamış alanlar bulunuyor. T.C. kimlik numarası doğrulaması yapılmadı.";
private static final String MESSAGE_LENGTH = "T.C. kimlik numarası 11 haneli olmalıdır.";
private static final String MESSAGE_UNEXPECTED_RESPONSE = "Nüfus müdürlüğü'nden beklenmedik yanıt alındı. İşlem tamamlanamadı.";
private static final String SERVICE_URL_IDENTITY_CARD_VALIDATION = "https://tckimlik.nvi.gov.tr/Service/KPSPublicV2.asmx";
private static final String SERVICE_URL_PERSON_VALIDATION = "https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx";
private static TCKNoValidator instance;
private final String urlIdentityCard;
private final String urlPerson;
private final MessageFactory messageFactory;

private TCKNoValidator() throws SOAPException {
urlIdentityCard = Optional.ofNullable(System.getProperty("com.aryaemini.nvi.url.identity-card"))
.orElseGet(() ->Optional.ofNullable(System.getenv("TCKN_VALIDATOR_IDENTITY_CARD_VALIDATION_URL"))
.orElse("https://tckimlik.nvi.gov.tr/Service/KPSPublicV2.asmx"));
urlPerson = Optional.ofNullable(System.getProperty("com.aryaemini.nvi.url.person"))
.orElseGet(() -> Optional.ofNullable(System.getenv("TCKN_VALIDATOR_PERSON_VALIDATION_URL"))
.orElse("https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx"));
messageFactory = MessageFactory.newInstance();
}

public static synchronized TCKNoValidator getInstance() {
logger.info("UYARI: Bu kütüphane, T.C. Kimlik Numarası doğrulama işlemleri için kullanılırken herhangi bir kişisel veri saklamaz veya depolamaz. Ancak, kütüphaneyi kullanan kişiler, Türkiye Cumhuriyeti Kanunları çerçevesinde \"VERİ SORUMLUSU\" olarak kabul edilebilir ve 6698 sayılı Kişisel Verilerin Korunması Kanunu (KVKK) gerekliliklerine uymakla yükümlüdür. Lütfen kişisel veri işlemlerinde gerekli yasal düzenlemelere dikkat ediniz.");
if (logger.isDebugEnabled()) {
logger.info("!!!DİKKAT!!! Kütüphaneyi şu anda hata ayıklama (debug) modunda kullanıyorsunuz. Bu modda, T.C. Kimlik Numarası ve diğer hassas bilgiler log kanalına iletilebilir. Hata ayıklama modunu kullanırken log kanalına aktarılan bu tür bilgilerin güvenliğinden ve korunmasından tamamen \"VERİ SORUMLUSU\" sıfatıyla kütüphaneyi kullanan kişi veya kurum sorumludur.\n6698 sayılı Kişisel Verilerin Korunması Kanunu (KVKK) çerçevesinde, bu bilgilerin korunmasına yönelik gerekli tedbirlerin alınması yasal zorunluluktur. Hata ayıklama modunu yalnızca güvenli bir ortamda kullanmanızı öneririz.");
}
try {
if (Objects.isNull(instance)) {
instance = new TCKNoValidator();
Expand Down Expand Up @@ -74,39 +89,72 @@ public boolean validate(Person person) {
try {
if (localValidate(person.getIdentityNumber())) {
SOAPMessage soapMessage = createCitizenSOAPRequest(person);
return request(soapMessage, SERVICE_URL_PERSON_VALIDATION);
return request(soapMessage, urlPerson);
}
return false;
} catch (EmptyFieldException | NullPointerException e) {
logger.trace(MESSAGE_EMPTY_FIELD, e);
return false;
if (logger.isDebugEnabled()) {
logger.info(e.getMessage() +
"\nT.C. Kimlik No : {}" +
"\nAdı : {}" +
"\nSoyadı : {}" +
"\nDoğum tarihi : {}",
person.getIdentityNumber(),
person.getFirstName(),
person.getLastName(),
person.getBirthYear(),
e);
} else {
logger.info(e.getMessage());
}
} catch (SOAPException e) {
throw new TCKNoValidationException(MESSAGE_UNEXPECTED_RESPONSE, e);
}
return false;
}

public boolean validate(IdentityCard identityCard) {
try {
if (localValidate(identityCard.getIdentityNumber())) {
SOAPMessage soapMessage = createIdentityCardSOAPRequest(identityCard);
return request(soapMessage, SERVICE_URL_IDENTITY_CARD_VALIDATION);
return request(soapMessage, urlIdentityCard);
}
return false;
} catch (EmptyFieldException e) {
logger.trace(e.getMessage(), e);
} catch (EmptyFieldException | NullPointerException e) {
if (logger.isDebugEnabled()) {
final var unspecified = "Belirtilmemiş";
logger.info(e.getMessage() +
"\nT.C. Kimlik No : {}" +
"\nAdı : {}" +
"\nSoyadı : {}" +
"\nDoğum Yılı : {}" +
"\nDoğum Gün : {}" +
"\nDoğum Ay : {}" +
"\nKimlik Seri No : {}",
identityCard.getIdentityNumber(),
identityCard.getFirstName(),
identityCard.isSurnameNotSpecified() ? unspecified : identityCard.getLastName(),
identityCard.getBirthYear(),
identityCard.isBirthDayNotSpecified() ? unspecified : identityCard.getBirthDay(),
identityCard.isBirthMonthNotSpecified() ? unspecified : identityCard.getBirthMonth(),
identityCard.validateIdCardNumber() ? (identityCard.getIdCardSerial() + " " + identityCard.getIdCardNumber()) : identityCard.getTckCardSerialNumber(),
e);
} else {
logger.trace(e.getMessage(), e);
}
return false;
} catch (SOAPException e) {
throw new TCKNoValidationException(MESSAGE_UNEXPECTED_RESPONSE, e);
}
}

private boolean request(SOAPMessage soapMessage, String url) {
private boolean request(SOAPMessage soapRequest, String url) {
logger.trace("Nüfus müdürlüğünden sorgulamaya hazırlanılıyor.");
var response = new AtomicReference<Boolean>();
try {
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
SOAPMessage soapResponse = soapConnection.call(soapMessage, url);
SOAPMessage soapResponse = soapConnection.call(soapRequest, url);
logRequest(url, soapRequest, soapResponse);
String responseBody = soapResponse.getSOAPBody().getTextContent();
response.setRelease(Boolean.parseBoolean(responseBody));
soapConnection.close();
Expand Down Expand Up @@ -186,4 +234,22 @@ private SOAPMessage createIdentityCardSOAPRequest(IdentityCard identityCard) thr
return soapMessage;
}

private void logRequest(String url, SOAPMessage soapRequest, SOAPMessage soapResponse) throws SOAPException {
if (logger.isTraceEnabled()) {
try (var outputStream = new ByteArrayOutputStream()) {
soapRequest.writeTo(outputStream);
var requestBody = outputStream.toString(StandardCharsets.UTF_8);
outputStream.reset();
soapResponse.writeTo(outputStream);
var responseBody = outputStream.toString(StandardCharsets.UTF_8);
MDC.put("requestBody", requestBody);
MDC.put("responseBody", responseBody);
logger.trace("Sending soap request to: {}", url);
MDC.clear();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}

}
2 changes: 2 additions & 0 deletions src/main/java/com/aryaemini/nvi/model/Citizen.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import com.aryaemini.nvi.interfaces.Person;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

import java.util.Calendar;
import java.util.Date;

@Builder
@Getter
@ToString
public class Citizen implements Person {

private String identityNumber;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/aryaemini/nvi/model/Identity.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import com.aryaemini.nvi.interfaces.IdentityCard;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

@Builder
@Getter
@ToString
public class Identity implements IdentityCard {

private String identityNumber;
Expand Down

0 comments on commit 9050d11

Please sign in to comment.