package org.xcolab.view.auth.handlers;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

import org.xcolab.client.members.MembersClient;
import org.xcolab.client.members.PermissionsClient;
import org.xcolab.client.members.pojo.Member;
import org.xcolab.commons.exceptions.InternalException;
import org.xcolab.view.auth.AuthenticationService;
import org.xcolab.view.pages.redballoon.utils.BalloonService;

import java.io.IOException;

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

public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    private final AuthenticationService authenticationService;
    private final BalloonService balloonService;
    private final boolean allowLogin;

    public AuthenticationSuccessHandler(AuthenticationService authenticationService,
            BalloonService balloonService, boolean allowLogin) {
        this.authenticationService = authenticationService;
        this.balloonService = balloonService;
        this.allowLogin = allowLogin;
        setDefaultTargetUrl("/");

        //TODO COLAB-2362: Rethink circular dependency
        authenticationService.setAuthenticationSuccessHandler(this);
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException {
        onAuthenticationSuccess(request, response, authentication, true);
    }

    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication, boolean redirectOnSuccess) throws IOException {
        final Member member = authenticationService.getRealMemberOrNull();

        if (!allowLogin && !PermissionsClient.canAdminAll(member)) {
            authenticationService.logout(request, response);
            getRedirectStrategy().sendRedirect(request, response, "/loginDisabled");
            return;
        }

        balloonService.associateBalloonTrackingWithUser(request, member);

        String refererHeader = request.getHeader(HttpHeaders.REFERER);
        MembersClient.createLoginLog(member.getId_(), request.getRemoteAddr(), refererHeader);

        if (redirectOnSuccess) {
            try {
                if (StringUtils.isNotBlank(refererHeader) && !refererHeader.endsWith("/login")) {
                    getRedirectStrategy().sendRedirect(request, response, refererHeader);
                } else {
                    super.onAuthenticationSuccess(request, response, authentication);
                }
            } catch (ServletException e) {
                // Not reachable - no ServletException is thrown by the implementations
                throw new InternalException(e);
            }
        }
    }
}

@@ -78,16 +78,73 @@
 gUtils;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -180,16 +180,16 @@
 eaders;%0A
-
 import o
@@ -917,16 +917,116 @@
 dler %7B%0A%0A
+    private static final Logger log = LoggerFactory.getLogger(AuthenticationSuccessHandler.class);%0A%0A
     priv
@@ -2066,32 +2066,32 @@
 s IOException %7B%0A
-
         final Me
@@ -2148,16 +2148,459 @@
 rNull();
+%0A        if (member == null) %7B%0A            // This can currently happen when there's an error during SSO%0A            // In that case, the CustomPrincipalExtractor returns null%0A            // An error message will already be saved in an AlertMessage%0A            log.warn(%22Member was null after authentication: %7B%7D%22, authentication.toString());%0A            getRedirectStrategy().sendRedirect(request, response, %22/%22);%0A            return;%0A        %7D
 %0A%0A      

Fix NPE when using deleted email