package com.ningdatech.pmapi.user.security.auth.password;

import com.ningdatech.basic.exception.BizException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author LiuXinXin
 * @Date 2020/8/3 8:46 下午
 * @Version 1.0
 **/
public class UsernamePasswordAuthFilter extends AbstractAuthenticationProcessingFilter {

    private boolean postOnly = true;

    private static final String USERNAME_PARAMETER = "username";
    private static final String PASSWORD_PARAMETER = "password";


    // ~ Constructors
    // ===================================================================================================

    public UsernamePasswordAuthFilter(String processingUrl) {
        super(new AntPathRequestMatcher(processingUrl, HttpMethod.POST.name()));
    }

    // ~ Methods
    // ========================================================================================================

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
            throw new AuthenticationServiceException("请求方法错误");
        }
        String username = request.getParameter(USERNAME_PARAMETER);
        String password = request.getParameter(PASSWORD_PARAMETER);
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            throw new UsernameNotFoundException("用户名或密码不能为空");
        }
        username = username.trim();
        password = password.trim();
        try {
            UsernamePasswordAuthToken authRequest = new UsernamePasswordAuthToken(username, password);
            // Allow subclasses to set the "details" property
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        } catch (AuthenticationException e) {
            throw new BadCredentialsException("账号或密码错误");
        } catch (BizException e) {
            throw new BadCredentialsException(e.getMessage());
        } catch (Exception e) {
            throw new InternalAuthenticationServiceException("授权失败：", e);
        }
    }

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
}
