package com.bls.auth.basic;

import org.mindrot.jbcrypt.BCrypt;

import com.bls.core.user.User;
import com.bls.dao.UserDao;
import com.google.common.base.Optional;

import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.basic.BasicCredentials;
import io.dropwizard.hibernate.UnitOfWork;

import static com.bls.AugmentedConfiguration.PW_HASH_SECURITY_LEVEL;

/**
 * Basic Authenticator class using plaintext credentials
 * Used to authenticate resources with @Auth annotation
 *
 * @param K entity key type for User
 */
public class BasicAuthenticator implements Authenticator<BasicCredentials, User> {

    private final UserDao<User> userDao;

    public BasicAuthenticator(UserDao<User> userDao) {this.userDao = userDao;}

    public static String generateSafeHash(final String plaintextPassword) {
        return BCrypt.hashpw(plaintextPassword, BCrypt.gensalt(PW_HASH_SECURITY_LEVEL));
    }

    private static boolean isMatched(final String plaintextPassword, final String hashed) {
        return BCrypt.checkpw(plaintextPassword, hashed);
    }

    @UnitOfWork
    public Optional<User> authenticate(final BasicCredentials basicCredentials) throws AuthenticationException {

        String email = basicCredentials.getUsername();
        String plaintextPassword = basicCredentials.getPassword();

        final Optional<User> user = userDao.findByEmail(email);
        if (user.isPresent() && isMatched(plaintextPassword, user.get().getPassword())) {
            return user;
        }
        return Optional.absent();
    }
}

@@ -412,16 +412,79 @@
 Y_LEVEL;
+%0Aimport static com.google.common.base.Preconditions.checkState;
 %0A%0A/**%0A *
@@ -1522,51 +1522,317 @@
 nt()
- && isMatched(plaintextPassword, user.get()
+) %7B%0A            final User existingUser = user.get();%0A            checkState(existingUser.getPassword() != null, %22Cannot authenticate: user with id: %25s (email: %25s) without password%22,%0A                    existingUser.getId(), existingUser.getEmail());%0A%0A            if (isMatched(plaintextPassword, existingUser
 .get
@@ -1854,24 +1854,28 @@
             
+    
 return user;
@@ -1875,16 +1875,30 @@
 n user;%0A
+            %7D%0A
         

Fix for NPE on authentication with incomplete user data