28 Şubat 2018 Çarşamba

JavaMail Properties Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.util.Properties;
Örnek
Şu alanlar doldurulur.
mail.port=25

mail.smtp.starttls.enable=true
mail.smtp.auth=true
mail.transport.protocol=smtp
mail.debug=true
mail.smtp.ssl.trust = localhost
mail.host = localhost
mail.username=XXXXXX
mail.password=XXXXXX
Örnek
Şu alanlar doldurulur.
Properties props = System.getProperties();
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Auth
Sunucunun bizi doğrulaması için kullanılır. Şöyle yaparız.
props.put("mail.smtp.auth", "true");
Debug
Şöyle yaparız.
props.put("mail.smtp.debug", "true");
Host ve Port
Şöyle yaparız.
props.put("mail.smtp.host", "mail.mydomain.com");
props.put("mail.smtp.port", "587");
SSL
SSL kullanmak için Properties içine verilen mail.smtp.ssl.enable anahtarı true yapılır. SMPT yerine POP3, IMAP gelebilir.

Şöyle yaparız.
props.put("mail.smtp.socketFactory.port", "465");    
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");  

TLS
Bağlantı kurulduktan sonra TLS'e geçmek için mail.smtp.starttls.enable anahtarı true yapılır.
props.put("mail.smtp.starttls.enable", "true");
Şu açıklama faydalı.
TLS is compulsory on 587 and any attempt to open a session without TLS yield the SMTP server error response "530 Must issue a STARTTLS command first". Then setting "mail.smtp.starttls.enable" to "true" alone still yield the same error "Could not convert socket to TLS" but now with a clue: "Server is not trusted". Indeed, you must have either a keystore defined in the JVM start properties that would contain a certificate chain ending onto a trusted root certificate, either enforce trust with this extra property: "mail.smtp.ssl.trust" set to the remote host name.


JavaMail PasswordAuthentication Sınıfı

Giriş
Şu satırı dahil ederiz.
import javax.mail.PasswordAuthentication;
Properties dosyasında şu satırı dahil ederiz. Kendi e-posta sucunumuza bağlantı açarken hesabımızı doğrulamak için kullanılır.
props.put("mail.smtp.auth", "true");
Örnek
Şöyle yaparız.
Properties props = new Properties();
...
Session session = Session.getInstance(props, new Authenticator() {
  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    String username = "abc@gmail.com";
    String password = "password";
    return new PasswordAuthentication(username,password); 
  }
});
Örnek
Şöyle yaparız.
Properties props = new Properties();    
props.put("mail.smtp.auth", "true");    
...
final String from="xxxx4@gmail.com";
final String password="xxxx";

//get Session   
Session session = Session.getDefaultInstance(props,new javax.mail.Authenticator() {    
  protected PasswordAuthentication getPasswordAuthentication() {    
    return new PasswordAuthentication(from,password);  
  }    
});    

SecretKeySpec Sınıfı

Giriş
Şu satırı dahil ederiz.
import javax.crypto.spec.SecretKeySpec;
Bu sınıf hem KeySpec hem de Key arayüzlerini gerçekleştirir.

Bu sınıf sadece algoritmayı bilir. Algoritmanın modları ve padding'i hakkında bilgisi yoktur. Algoritmanın modu ve padding'i Cipher sınıfını ilgilendirir.

Yani bu sınıf aslında sadece Ciper.init() Mac.init() gibi metodlara daha kolay parametre geçmek içindir.

Bazı kodlarda KeyGenerator ile key ürettiriliyor. Bu kullanım tarzını hiç anlamadım.

KeySpec Arayüzü 
KeySpec arayüzü Cipher ilklendirmek için değil key hakkında metadata vermek içindir.

Key Arayüzü
SecretKey arayüzünden kalıtır. SecretKey ise Key arayüzünden kalıtır. Key nesneleri Cipher nesnesini ilklendirmek için gerekir. Açıklaması şöyle
This class specifies a secret key in a provider-independent fashion.
It can be used to construct a SecretKey from a byte array, without having to go through a (provider-based) SecretKeyFactory.
Bu sınıf Cipher nesnesini ilklendirmek için kullanılır. Şöyle yaparız.
Key key = new SecretKeySpec(..., "...");
Cipher encryptCipher = Cipher.getInstance("...");
encryptCipher.init (Cipher.ENCRYPT_MODE, key);
Bu sınıfı direkt kullanmak veya SecretKeyFactory ile yaratmak arasında güvenlik açısından fark olup olmadığını bilmiyorum.

constructor - byte [] + Algoritma
Örnek
Şöyle yaparız.
String strDefaultKey = "...";
byte [] bytes = strDefaultKey.getBytes ("UTF-8");
SecretKeySpec keySpec = new SecretKeySpec (bytes, "AES");
Örnek
Şöyle yaparız.
String strDefaultKey = "...";
byte [] bytes = strDefaultKey.getBytes ("UTF-8");
Key keySpec = new SecretKeySpec (bytes, "DES");
Örnek
Şöyle yaparız.
String HMAC_SHA1_ALGORITHM = "HmacSHA1";

String key = ...;

SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);

27 Şubat 2018 Salı

JUnit @Parameterized.Parameters Anotasyonu

Giriş
Testin her parametre için ayrı ayrı koşmasını sağlar. Test sınıfının her parametreyi alan bir constructor metodu bulunur.

Örnek
Elimizde şöyle bir kod olsun
public class CalculatorImpl implements Calculator {
 
  @Override
  public double process(String expression) {
    ...
  }
}
Test verisi için şöyle yaparız. Birinci değer girdi string, ikinci değer sonuç, üçündü değer eper varsa exception'dır
@RunWith(Parameterized.class)
public class CalculatorTest {
  @Parameters(name = "{index}: CalculatorTest({0})={1}, throws {2}")
  public static Collection<Object[]> data() {
    return Arrays.asList(new Object[][]{
      {"1 + 1", 2, null},
      {"1 + 1 + 1", 3, null},
      {"1–1", 0, null},
      {"1 * 1", 1, null},
      {"1 / 1", 1, null},
      {"( 1 + 1 )", 2, null},
      {"+", 0, new CalculatorException("Invalid expression: +")},
      {"1 1", 0, new CalculatorException("Invalid expression: 1 1")}
    });
  }

  private final String input;
  private final double expected;
  private final Exception exception;
  
  public CalculatorTest(String input, double expected, Exception exception) {
    this.input = input;
    this.expected = expected;
    this.exception = exception;
  }
...
}
Test için şöyle yaparız
@Test
public void testProcess() {
  Calculator c = new CalculatorImpl();
  try {
    double result = c.process(input);
    if (exception != null) {
      fail("should have thrown an exception: " + exception);
    }
    // shouldn't compare doubles without a delta, because FP math isn't accurate
    assertEquals(expected, result, 0.000001);
  } catch (Exception e) {
   if (exception == null) {
     fail("should not have thrown an exception, but threw " + e);
   }
   if (!exception.getClass().equals(e.getClass()) ||
!exception.getMessage().equals(e.getMessage())) {
     fail("expected exception " + exception + "; got exception " + e);
   }
  }
}
Örnek

Bu örnekte her test 1 ve 2 değerleri için koşar. Şöyle yaparız.
@RunWith(value = Parameterized.class)
public class MyTest {

  private int value;

  @Parameterized.Parameters
  public static List<Object[]> data() {
    return Arrays.asList(new Object[][]{
        {1},
        {2},
    });
  }

  public MyTest(int value) {
    this.value = value;
  }

  @Test
  public void test1() {
    ...
  }

  @Test
  public void test2() {
    ...
  }
}