package de.zalando.aruha.nakadi.security;

import de.zalando.aruha.nakadi.config.SecuritySettings;
import de.zalando.aruha.nakadi.util.FeatureToggleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.security.oauth2.common.exceptions.UnauthorizedUserException;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.security.Principal;
import java.util.Optional;

import static de.zalando.aruha.nakadi.util.FeatureToggleService.Feature.CHECK_APPLICATION_LEVEL_PERMISSIONS;

public class ClientResolver implements HandlerMethodArgumentResolver {

    private final SecuritySettings settings;
    private final FeatureToggleService featureToggleService;

    @Autowired
    public ClientResolver(SecuritySettings settings, FeatureToggleService featureToggleService) {
        this.settings = settings;
        this.featureToggleService = featureToggleService;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(Client.class);
    }

    @Override
    public Client resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest request, WebDataBinderFactory binderFactory) throws Exception
    {
        if (!featureToggleService.isFeatureEnabled(CHECK_APPLICATION_LEVEL_PERMISSIONS)) {
            return Client.PERMIT_ALL;
        }

        final Optional<String> clientId = Optional.ofNullable(request.getUserPrincipal()).map(Principal::getName);
        if (clientId.filter(settings.getAdminClientId()::equals).isPresent()) {
            return Client.PERMIT_ALL;
        }
        final Optional<Client> principal = clientId.map(Client.Authorized::new);
        if (settings.getAuthMode() == SecuritySettings.AuthMode.OFF) {
            return principal.orElseGet(() -> Client.PERMIT_ALL);
        }
        return principal.orElseThrow(() -> new UnauthorizedUserException("Client unauthorized"));
    }
}

@@ -688,16 +688,92 @@
 ional;%0A%0A
+import static de.zalando.aruha.nakadi.config.SecuritySettings.AuthMode.OFF;%0A
 import s
@@ -1670,181 +1670,14 @@
     
-if (!featureToggleService.isFeatureEnabled(CHECK_APPLICATION_LEVEL_PERMISSIONS)) %7B%0A            return Client.PERMIT_ALL;%0A        %7D%0A%0A        final Optional%3CString%3E clientId =
+return
  Opt
@@ -1720,16 +1720,33 @@
 cipal())
+%0A                
 .map(Pri
@@ -1765,334 +1765,421 @@
 ame)
-;%0A        if (clientId.filter(settings.getAdminClientId()::equals).isPresent()) %7B%0A            return Client.PERMIT_ALL;%0A   
+%0A                .map(this::resolveClient)%0A                .orElseThrow(() -%3E new UnauthorizedUserException(%22Client unauthorized%22));%0A
     
- 
 %7D
+%0A
 %0A    
-    final Optional%3CClient%3E principal = clientId.map(Client.Authorized::new);%0A        if (settings.getAuthMode() == SecuritySettings.AuthMode.OFF) %7B%0A            return principal.orElseGet(() -%3E
+private Client resolveClient(String clientId) %7B%0A        return !featureToggleService.isFeatureEnabled(CHECK_APPLICATION_LEVEL_PERMISSIONS)%0A                %7C%7C settings.getAuthMode() == OFF%0A                %7C%7C settings.getAdminClientId().equals(clientId)%0A                ?
  Cli
@@ -2192,18 +2192,16 @@
 RMIT_ALL
-);
 %0A       
@@ -2205,18 +2205,16 @@
     
-%7D%0A
         
 retu
@@ -2213,95 +2213,40 @@
     
-return principal.orElseThrow(() -%3E new UnauthorizedUserException(%22Client unauthorized%22)
+: new Client.Authorized(clientId
 );%0A 

simplify client resolving