/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package httpauthenticationmechanism;

import javax.enterprise.context.ApplicationScoped;
import javax.security.enterprise.credential.CallerOnlyCredential;
import javax.security.enterprise.credential.Credential;
import javax.security.enterprise.credential.UsernamePasswordCredential;
import javax.security.enterprise.identitystore.CredentialValidationResult;
import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT;
import static javax.security.enterprise.identitystore.CredentialValidationResult.NOT_VALIDATED_RESULT;
import javax.security.enterprise.identitystore.IdentityStore;

import business.user.PersonManager;
import exception.InvalidCredentialException;
import java.util.Set;
import java.util.stream.Collectors;
import javax.ejb.EJB;
import model.person.Person;

/**
 *
 * @author Patrick
 */
@ApplicationScoped
public class AppIdentityStore implements IdentityStore {

    @EJB
    PersonManager userManager;
    
    @Override
    public int priority() {
        return 90;
    }

    @Override
    public CredentialValidationResult validate(Credential credential) {
        try {

            // check if the credential was UsernamePasswordCredential
            if (credential instanceof UsernamePasswordCredential) {
                String username = ((UsernamePasswordCredential) credential).getCaller();
                String password = ((UsernamePasswordCredential) credential).getPasswordAsString();

                return validate(this.userManager.getByEmailAndPassword(username, password));
            }

            // check if the credential was CallerOnlyCredential
            if (credential instanceof CallerOnlyCredential) {
                String username = ((CallerOnlyCredential) credential).getCaller();

                return validate(
                        this.userManager.getByEmail(username)
                                .orElseThrow(InvalidCredentialException::new)
                );
            }

        } catch (InvalidCredentialException e) {
            return INVALID_RESULT;
        }
        return NOT_VALIDATED_RESULT;
    }

    private CredentialValidationResult validate(Person person) {
        Set<String> groups;
        
        groups = person.getUserGroups().stream()
                .map(gr -> gr.toString())
                .collect(Collectors.toSet());

        return new CredentialValidationResult(person.getEmail(), groups);
    }

}
