/*
 * Copyright 2014-2016 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.frontend.find.idol.beanconfiguration;

import com.hp.autonomy.frontend.configuration.authentication.CommunityPrincipal;
import com.hp.autonomy.frontend.find.core.savedsearches.UserEntity;
import com.hp.autonomy.frontend.find.core.savedsearches.UserEntityRepository;
import com.hpe.bigdata.frontend.spring.authentication.AuthenticationInformationRetriever;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class IdolLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    private final String configUrl;
    private final String applicationUrl;
    private final String roleDefault;
    private final AuthenticationInformationRetriever<?, ?> authenticationInformationRetriever;
    private final UserEntityRepository userEntityRepository;

    public IdolLoginSuccessHandler(
            final String configUrl,
            final String applicationUrl,
            final String roleDefault,
            final AuthenticationInformationRetriever<?, ?> authenticationInformationRetriever,
            final UserEntityRepository userEntityRepository
            ) {
        this.configUrl = configUrl;
        this.applicationUrl = applicationUrl;
        this.roleDefault = roleDefault;
        this.authenticationInformationRetriever = authenticationInformationRetriever;
        this.userEntityRepository = userEntityRepository;
    }

    @Override
    public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response, final Authentication authentication) throws ServletException, IOException {
        final CommunityPrincipal principal = (CommunityPrincipal) authenticationInformationRetriever.getPrincipal();

        if(principal != null) {
            final UserEntity currentUser =  new UserEntity();
            currentUser.setUsername(principal.getUsername());

            final UserEntity persistedUser = userEntityRepository.findByDomainAndUserStoreAndUuidAndUsername(
                    null,
                    null,
                    null,
                    currentUser.getUsername()
            );

            if (persistedUser == null) {
                userEntityRepository.saveAndFlush(currentUser);
            }
        }

        super.onAuthenticationSuccess(request, response, authentication);
    }

    @Override
    protected String determineTargetUrl(final HttpServletRequest request, final HttpServletResponse response) {
        final Authentication authentication = authenticationInformationRetriever.getAuthentication();

        for (final GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
            final String authority = grantedAuthority.getAuthority();

            if (roleDefault.equalsIgnoreCase(authority)) {
                return configUrl;
            }
        }

        return applicationUrl;
    }
}

@@ -1312,21 +1312,68 @@
 ;%0A%0A    p
-ublic
+rivate final Object newUserLock = new Object();%0A%0A   
  IdolLog
@@ -1660,24 +1660,16 @@
 ository%0A
-        
     ) %7B%0A
@@ -1933,32 +1933,128 @@
 ository;%0A    %7D%0A%0A
+    // Check if we have a user entity for the current user in the database, if not, create one.%0A
     @Override%0A  
@@ -2237,16 +2237,95 @@
 ption %7B%0A
+        if (authentication.getPrincipal() instanceof CommunityPrincipal) %7B%0A    
         
@@ -2433,25 +2433,28 @@
 ipal();%0A
-%0A
+    
         
 if(princ
@@ -2449,31 +2449,66 @@
     
-if(principal != null) %7B
+final String principalUsername = principal.getUsername();%0A
 %0A   
@@ -2537,28 +2537,25 @@
 ity 
-current
+persisted
 User = 
- new U
+u
 serE
@@ -2559,20 +2559,63 @@
 erEntity
-(
+Repository.findByUsername(principalUsername
 );%0A
+%0A
         
@@ -2622,59 +2622,312 @@
     
-currentUser.setUsername(principal.getUsername());%0A%0A
+if (persistedUser == null) %7B%0A                // Ensure if, say, two applications log in as the same user at same time, one will be made to wait for lock.%0A                synchronized (newUserLock) %7B%0A                    // Check that there is still no existing user entity after lock is released.%0A        
     
@@ -2956,32 +2956,33 @@
 ty persistedUser
+2
  = userEntityRep
@@ -2999,44 +2999,34 @@
 ndBy
-DomainAndUserStoreAndUuidAnd
+Username(principal
 Username
 (%0A  
@@ -3021,17 +3021,19 @@
 Username
-(
+);%0A
 %0A       
@@ -3036,38 +3036,62 @@
                 
+ if (persistedUser2 ==
  null
-,
+) %7B
 %0A               
@@ -3099,40 +3099,65 @@
     
-null,%0A                    null,%0A
+    final UserEntity currentUser = new UserEntity();%0A    
     
@@ -3184,17 +3184,17 @@
 entUser.
-g
+s
 etUserna
@@ -3200,67 +3200,37 @@
 ame(
-)%0A            );%0A%0A            if (persistedUser == null) %7B%0A
+principalUsername);%0A%0A        
     
@@ -3270,16 +3270,8 @@
 save
-AndFlush
 (cur
@@ -3281,16 +3281,56 @@
 tUser);%0A
+                    %7D%0A                %7D%0A
         

Improve how user entities are saved to the database on app login