text:
package org.apereo.cas.oidc.config;

import org.apereo.cas.CentralAuthenticationService;
import org.apereo.cas.audit.AuditableExecution;
import org.apereo.cas.authentication.AuthenticationServiceSelectionPlan;
import org.apereo.cas.authentication.AuthenticationServiceSelectionStrategy;
import org.apereo.cas.authentication.AuthenticationSystemSupport;
import org.apereo.cas.authentication.MultifactorAuthenticationProviderResolver;
import org.apereo.cas.authentication.MultifactorAuthenticationTrigger;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.authentication.principal.PrincipalFactoryUtils;
import org.apereo.cas.authentication.principal.ServiceFactory;
import org.apereo.cas.authentication.principal.WebApplicationService;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.logout.LogoutExecutionPlanConfigurer;
import org.apereo.cas.logout.slo.SingleLogoutMessageCreator;
import org.apereo.cas.logout.slo.SingleLogoutServiceLogoutUrlBuilder;
import org.apereo.cas.logout.slo.SingleLogoutServiceMessageHandler;
import org.apereo.cas.oidc.OidcConstants;
import org.apereo.cas.oidc.authn.OidcAccessTokenAuthenticator;
import org.apereo.cas.oidc.authn.OidcClientConfigurationAccessTokenAuthenticator;
import org.apereo.cas.oidc.authn.OidcClientSecretJwtAuthenticator;
import org.apereo.cas.oidc.authn.OidcPrivateKeyJwtAuthenticator;
import org.apereo.cas.oidc.claims.OidcCustomScopeAttributeReleasePolicy;
import org.apereo.cas.oidc.claims.mapping.OidcAttributeToScopeClaimMapper;
import org.apereo.cas.oidc.claims.mapping.OidcDefaultAttributeToScopeClaimMapper;
import org.apereo.cas.oidc.discovery.OidcServerDiscoverySettings;
import org.apereo.cas.oidc.discovery.OidcServerDiscoverySettingsFactory;
import org.apereo.cas.oidc.discovery.webfinger.OidcWebFingerDiscoveryService;
import org.apereo.cas.oidc.discovery.webfinger.OidcWebFingerUserInfoRepository;
import org.apereo.cas.oidc.discovery.webfinger.userinfo.OidcEchoingWebFingerUserInfoRepository;
import org.apereo.cas.oidc.discovery.webfinger.userinfo.OidcGroovyWebFingerUserInfoRepository;
import org.apereo.cas.oidc.discovery.webfinger.userinfo.OidcRestfulWebFingerUserInfoRepository;
import org.apereo.cas.oidc.dynareg.OidcClientRegistrationRequest;
import org.apereo.cas.oidc.dynareg.OidcClientRegistrationRequestSerializer;
import org.apereo.cas.oidc.jwks.OidcDefaultJsonWebKeystoreCacheLoader;
import org.apereo.cas.oidc.jwks.OidcJsonWebKeystoreGeneratorService;
import org.apereo.cas.oidc.jwks.OidcServiceJsonWebKeystoreCacheExpirationPolicy;
import org.apereo.cas.oidc.jwks.OidcServiceJsonWebKeystoreCacheLoader;
import org.apereo.cas.oidc.jwks.generator.OidcDefaultJsonWebKeystoreGeneratorService;
import org.apereo.cas.oidc.jwks.generator.OidcRestfulJsonWebKeystoreGeneratorService;
import org.apereo.cas.oidc.profile.OidcProfileScopeToAttributesFilter;
import org.apereo.cas.oidc.profile.OidcUserProfileDataCreator;
import org.apereo.cas.oidc.profile.OidcUserProfileSigningAndEncryptionService;
import org.apereo.cas.oidc.profile.OidcUserProfileViewRenderer;
import org.apereo.cas.oidc.services.OidcServiceRegistryListener;
import org.apereo.cas.oidc.slo.OidcSingleLogoutMessageCreator;
import org.apereo.cas.oidc.slo.OidcSingleLogoutServiceMessageHandler;
import org.apereo.cas.oidc.token.OidcIdTokenGeneratorService;
import org.apereo.cas.oidc.token.OidcIdTokenSigningAndEncryptionService;
import org.apereo.cas.oidc.token.OidcRegisteredServiceJwtAccessTokenCipherExecutor;
import org.apereo.cas.oidc.util.OidcAuthorizationRequestSupport;
import org.apereo.cas.oidc.web.OidcAccessTokenResponseGenerator;
import org.apereo.cas.oidc.web.OidcCallbackAuthorizeViewResolver;
import org.apereo.cas.oidc.web.OidcCasClientRedirectActionBuilder;
import org.apereo.cas.oidc.web.OidcConsentApprovalViewResolver;
import org.apereo.cas.oidc.web.OidcHandlerInterceptorAdapter;
import org.apereo.cas.oidc.web.OidcImplicitIdTokenAndTokenAuthorizationResponseBuilder;
import org.apereo.cas.oidc.web.OidcImplicitIdTokenAuthorizationResponseBuilder;
import org.apereo.cas.oidc.web.OidcSecurityInterceptor;
import org.apereo.cas.oidc.web.controllers.authorize.OidcAuthorizeEndpointController;
import org.apereo.cas.oidc.web.controllers.discovery.OidcWellKnownEndpointController;
import org.apereo.cas.oidc.web.controllers.dynareg.OidcClientConfigurationEndpointController;
import org.apereo.cas.oidc.web.controllers.dynareg.OidcDynamicClientRegistrationEndpointController;
import org.apereo.cas.oidc.web.controllers.introspection.OidcIntrospectionEndpointController;
import org.apereo.cas.oidc.web.controllers.jwks.OidcJwksEndpointController;
import org.apereo.cas.oidc.web.controllers.logout.OidcLogoutEndpointController;
import org.apereo.cas.oidc.web.controllers.profile.OidcUserProfileEndpointController;
import org.apereo.cas.oidc.web.controllers.token.OidcAccessTokenEndpointController;
import org.apereo.cas.oidc.web.controllers.token.OidcRevocationEndpointController;
import org.apereo.cas.oidc.web.flow.OidcMultifactorAuthenticationTrigger;
import org.apereo.cas.oidc.web.flow.OidcRegisteredServiceUIAction;
import org.apereo.cas.oidc.web.flow.OidcWebflowConfigurer;
import org.apereo.cas.services.RegisteredServiceCipherExecutor;
import org.apereo.cas.services.ServiceRegistryListener;
import org.apereo.cas.services.ServicesManager;
import org.apereo.cas.support.oauth.OAuth20Constants;
import org.apereo.cas.support.oauth.authenticator.Authenticators;
import org.apereo.cas.support.oauth.authenticator.OAuth20CasAuthenticationBuilder;
import org.apereo.cas.support.oauth.authenticator.OAuthAuthenticationClientProvider;
import org.apereo.cas.support.oauth.profile.OAuth20ProfileScopeToAttributesFilter;
import org.apereo.cas.support.oauth.profile.OAuth20UserProfileDataCreator;
import org.apereo.cas.support.oauth.services.OAuthRegisteredService;
import org.apereo.cas.support.oauth.validator.authorization.OAuth20AuthorizationRequestValidator;
import org.apereo.cas.support.oauth.validator.token.OAuth20TokenRequestValidator;
import org.apereo.cas.support.oauth.web.endpoints.OAuth20ConfigurationContext;
import org.apereo.cas.support.oauth.web.response.OAuth20CasClientRedirectActionBuilder;
import org.apereo.cas.support.oauth.web.response.accesstoken.OAuth20TokenGenerator;
import org.apereo.cas.support.oauth.web.response.accesstoken.ext.AccessTokenGrantRequestExtractor;
import org.apereo.cas.support.oauth.web.response.accesstoken.response.OAuth20AccessTokenResponseGenerator;
import org.apereo.cas.support.oauth.web.response.callback.OAuth20AuthorizationResponseBuilder;
import org.apereo.cas.support.oauth.web.views.ConsentApprovalViewResolver;
import org.apereo.cas.support.oauth.web.views.OAuth20CallbackAuthorizeViewResolver;
import org.apereo.cas.support.oauth.web.views.OAuth20UserProfileViewRenderer;
import org.apereo.cas.ticket.ExpirationPolicyBuilder;
import org.apereo.cas.ticket.IdTokenGeneratorService;
import org.apereo.cas.ticket.OAuth20TokenSigningAndEncryptionService;
import org.apereo.cas.ticket.accesstoken.OAuth20AccessTokenFactory;
import org.apereo.cas.ticket.code.OAuth20CodeFactory;
import org.apereo.cas.ticket.device.OAuth20DeviceTokenFactory;
import org.apereo.cas.ticket.registry.TicketRegistry;
import org.apereo.cas.ticket.registry.TicketRegistrySupport;
import org.apereo.cas.token.JwtBuilder;
import org.apereo.cas.util.CollectionUtils;
import org.apereo.cas.util.crypto.CipherExecutor;
import org.apereo.cas.util.gen.DefaultRandomStringGenerator;
import org.apereo.cas.util.http.HttpClient;
import org.apereo.cas.util.serialization.StringSerializer;
import org.apereo.cas.validation.CasProtocolViewFactory;
import org.apereo.cas.web.cookie.CasCookieBuilder;
import org.apereo.cas.web.flow.CasWebflowConfigurer;
import org.apereo.cas.web.flow.CasWebflowExecutionPlanConfigurer;
import org.apereo.cas.web.flow.resolver.CasDelegatingWebflowEventResolver;
import org.apereo.cas.web.flow.resolver.CasWebflowEventResolver;
import org.apereo.cas.web.flow.resolver.impl.CasWebflowEventResolutionConfigurationContext;
import org.apereo.cas.web.flow.resolver.impl.mfa.DefaultMultifactorAuthenticationProviderWebflowEventResolver;

import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.jose4j.jwk.PublicJsonWebKey;
import org.pac4j.cas.client.CasClient;
import org.pac4j.core.authorization.authorizer.DefaultAuthorizers;
import org.pac4j.core.config.Config;
import org.pac4j.core.context.session.SessionStore;
import org.pac4j.core.credentials.TokenCredentials;
import org.pac4j.core.credentials.authenticator.Authenticator;
import org.pac4j.core.credentials.extractor.BearerAuthExtractor;
import org.pac4j.core.http.adapter.JEEHttpActionAdapter;
import org.pac4j.http.client.direct.DirectFormClient;
import org.pac4j.http.client.direct.HeaderClient;
import org.pac4j.springframework.web.SecurityInterceptor;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
import org.springframework.webflow.execution.Action;

import java.time.Duration;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * This is {@link OidcConfiguration}.
 *
 * @author Misagh Moayyed
 * @since 5.0.0
 */
@Configuration("oidcConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
@Slf4j
public class OidcConfiguration implements WebMvcConfigurer {
    @Autowired
    @Qualifier("oauthRegisteredServiceCipherExecutor")
    private ObjectProvider<CipherExecutor> oauthRegisteredServiceCipherExecutor;

    @Autowired
    @Qualifier("oauthDistributedSessionStore")
    private ObjectProvider<SessionStore> oauthDistributedSessionStore;

    @Autowired
    @Qualifier("accessTokenJwtBuilder")
    private ObjectProvider<JwtBuilder> accessTokenJwtBuilder;

    @Autowired
    @Qualifier("accessTokenGrantAuditableRequestExtractor")
    private ObjectProvider<AuditableExecution> accessTokenGrantAuditableRequestExtractor;

    @Autowired
    @Qualifier("defaultAuthenticationSystemSupport")
    private ObjectProvider<AuthenticationSystemSupport> authenticationSystemSupport;

    @Autowired
    @Qualifier("registeredServiceAccessStrategyEnforcer")
    private ObjectProvider<AuditableExecution> registeredServiceAccessStrategyEnforcer;

    @Autowired
    @Qualifier("oauthAuthorizationRequestValidators")
    private ObjectProvider<Set<OAuth20AuthorizationRequestValidator>> oauthRequestValidators;

    @Autowired
    @Qualifier("grantingTicketExpirationPolicy")
    private ObjectProvider<ExpirationPolicyBuilder> grantingTicketExpirationPolicy;

    @Autowired
    @Qualifier("oauthTokenGenerator")
    private ObjectProvider<OAuth20TokenGenerator> oauthTokenGenerator;

    @Autowired
    @Qualifier("oauthAuthorizationResponseBuilders")
    private ObjectProvider<Set<OAuth20AuthorizationResponseBuilder>> oauthAuthorizationResponseBuilders;

    @Autowired
    @Qualifier("webApplicationServiceFactory")
    private ObjectProvider<ServiceFactory<WebApplicationService>> webApplicationServiceFactory;

    @Autowired
    @Qualifier("accessTokenExpirationPolicy")
    private ObjectProvider<ExpirationPolicyBuilder> accessTokenExpirationPolicy;

    @Autowired
    @Qualifier("deviceTokenExpirationPolicy")
    private ObjectProvider<ExpirationPolicyBuilder> deviceTokenExpirationPolicy;

    @Autowired
    @Qualifier("requiresAuthenticationAccessTokenInterceptor")
    private ObjectProvider<SecurityInterceptor> requiresAuthenticationAccessTokenInterceptor;

    @Autowired
    @Qualifier("oauthCasAuthenticationBuilder")
    private ObjectProvider<OAuth20CasAuthenticationBuilder> authenticationBuilder;

    @Autowired
    @Qualifier("warnCookieGenerator")
    private ObjectProvider<CasCookieBuilder> warnCookieGenerator;

    @Autowired
    @Qualifier("loginFlowRegistry")
    private ObjectProvider<FlowDefinitionRegistry> loginFlowDefinitionRegistry;

    @Autowired
    @Qualifier("logoutFlowRegistry")
    private ObjectProvider<FlowDefinitionRegistry> logoutFlowDefinitionRegistry;

    @Autowired
    private ObjectProvider<FlowBuilderServices> flowBuilderServices;

    @Autowired
    @Qualifier("initialAuthenticationAttemptWebflowEventResolver")
    private ObjectProvider<CasDelegatingWebflowEventResolver> initialAuthenticationAttemptWebflowEventResolver;

    @Autowired
    @Qualifier("centralAuthenticationService")
    private ObjectProvider<CentralAuthenticationService> centralAuthenticationService;

    @Autowired
    @Qualifier("oauth20AuthenticationRequestServiceSelectionStrategy")
    private ObjectProvider<AuthenticationServiceSelectionStrategy> oauth20AuthenticationServiceSelectionStrategy;

    @Autowired
    private CasConfigurationProperties casProperties;

    @Autowired
    @Qualifier("casProtocolViewFactory")
    private ObjectProvider<CasProtocolViewFactory> casProtocolViewFactory;

    @Autowired
    private ResourceLoader resourceLoader;

    @Autowired
    @Qualifier("singleLogoutServiceLogoutUrlBuilder")
    private ObjectProvider<SingleLogoutServiceLogoutUrlBuilder> singleLogoutServiceLogoutUrlBuilder;

    @Autowired
    @Qualifier("oauthSecConfig")
    private ObjectProvider<Config> oauthSecConfig;

    @Autowired
    @Qualifier("ticketGrantingTicketCookieGenerator")
    private ObjectProvider<CasCookieBuilder> ticketGrantingTicketCookieGenerator;

    @Autowired
    @Qualifier("defaultTicketRegistrySupport")
    private ObjectProvider<TicketRegistrySupport> ticketRegistrySupport;

    @Autowired
    @Qualifier("defaultAccessTokenFactory")
    private ObjectProvider<OAuth20AccessTokenFactory> defaultAccessTokenFactory;

    @Autowired
    @Qualifier("defaultDeviceTokenFactory")
    private ObjectProvider<OAuth20DeviceTokenFactory> defaultDeviceTokenFactory;

    @Autowired
    @Qualifier("servicesManager")
    private ObjectProvider<ServicesManager> servicesManager;

    @Autowired
    @Qualifier("ticketRegistry")
    private ObjectProvider<TicketRegistry> ticketRegistry;

    @Autowired
    @Qualifier("defaultOAuthCodeFactory")
    private ObjectProvider<OAuth20CodeFactory> defaultOAuthCodeFactory;

    @Autowired
    private ConfigurableApplicationContext applicationContext;

    @Autowired
    @Qualifier("authenticationServiceSelectionPlan")
    private ObjectProvider<AuthenticationServiceSelectionPlan> authenticationRequestServiceSelectionStrategies;

    @Autowired
    @Qualifier("accessTokenGrantRequestExtractors")
    private ObjectProvider<Collection<AccessTokenGrantRequestExtractor>> accessTokenGrantRequestExtractors;

    @Autowired
    @Qualifier("oauthTokenRequestValidators")
    private ObjectProvider<Collection<OAuth20TokenRequestValidator>> oauthTokenRequestValidators;

    @Autowired
    @Qualifier("multifactorAuthenticationProviderResolver")
    private ObjectProvider<MultifactorAuthenticationProviderResolver> multifactorAuthenticationProviderResolver;

    @Autowired
    @Qualifier("noRedirectHttpClient")
    private ObjectProvider<HttpClient> httpClient;

    @Autowired
    @Qualifier("authenticationServiceSelectionPlan")
    private ObjectProvider<AuthenticationServiceSelectionPlan> authenticationServiceSelectionPlan;

    @Override
    public void addInterceptors(final InterceptorRegistry registry) {
        registry.addInterceptor(oauthInterceptor()).addPathPatterns('/' + OidcConstants.BASE_OIDC_URL.concat("/").concat("*"));
    }

    @Bean
    public ConsentApprovalViewResolver consentApprovalViewResolver() {
        return new OidcConsentApprovalViewResolver(casProperties);
    }

    @Bean
    public OAuth20CallbackAuthorizeViewResolver callbackAuthorizeViewResolver() {
        return new OidcCallbackAuthorizeViewResolver();
    }

    @Bean
    public OAuth20CasClientRedirectActionBuilder oauthCasClientRedirectActionBuilder() {
        return new OidcCasClientRedirectActionBuilder(oidcAuthorizationRequestSupport());
    }

    @Bean
    public HandlerInterceptorAdapter requiresAuthenticationDynamicRegistrationInterceptor() {
        val clients = String.join(",",
            Authenticators.CAS_OAUTH_CLIENT_BASIC_AUTHN,
            Authenticators.CAS_OAUTH_CLIENT_ACCESS_TOKEN_AUTHN,
            Authenticators.CAS_OAUTH_CLIENT_DIRECT_FORM,
            Authenticators.CAS_OAUTH_CLIENT_USER_FORM);
        val interceptor = new SecurityInterceptor(oauthSecConfig.getObject(), clients, JEEHttpActionAdapter.INSTANCE);
        interceptor.setAuthorizers(DefaultAuthorizers.IS_FULLY_AUTHENTICATED);
        return interceptor;
    }

    @Bean
    public HandlerInterceptorAdapter requiresAuthenticationClientConfigurationInterceptor() {
        val clients = String.join(",", OidcConstants.CAS_OAUTH_CLIENT_CONFIG_ACCESS_TOKEN_AUTHN);
        val interceptor = new SecurityInterceptor(oauthSecConfig.getObject(), clients, JEEHttpActionAdapter.INSTANCE);
        interceptor.setAuthorizers(DefaultAuthorizers.IS_FULLY_AUTHENTICATED);
        return interceptor;
    }

    @Bean
    public HandlerInterceptorAdapter requiresAuthenticationAuthorizeInterceptor() {
        val name = oauthSecConfig.getObject().getClients()
            .findClient(CasClient.class)
            .orElseThrow()
            .getName();
        val interceptor = new OidcSecurityInterceptor(oauthSecConfig.getObject(), name,
            oidcAuthorizationRequestSupport(),
            oauthDistributedSessionStore.getObject());

        return interceptor;
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcCasClientRedirectActionBuilder")
    @RefreshScope
    public OAuth20CasClientRedirectActionBuilder oidcCasClientRedirectActionBuilder() {
        return new OidcCasClientRedirectActionBuilder(oidcAuthorizationRequestSupport());
    }

    @RefreshScope
    @ConditionalOnMissingBean(name = "oidcIdTokenGenerator")
    @Bean
    public IdTokenGeneratorService oidcIdTokenGenerator() {
        val context = buildConfigurationContext();
        context.setIdTokenSigningAndEncryptionService(oidcTokenSigningAndEncryptionService());
        return new OidcIdTokenGeneratorService(context);
    }

    @ConditionalOnMissingBean(name = "oidcAccessTokenResponseGenerator")
    @Bean
    @RefreshScope
    public OAuth20AccessTokenResponseGenerator oidcAccessTokenResponseGenerator() {
        return new OidcAccessTokenResponseGenerator(oidcIdTokenGenerator(),
            accessTokenJwtBuilder.getObject(), casProperties);
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcAuthorizationRequestSupport")
    public OidcAuthorizationRequestSupport oidcAuthorizationRequestSupport() {
        return new OidcAuthorizationRequestSupport(ticketGrantingTicketCookieGenerator.getObject(), ticketRegistrySupport.getObject());
    }

    @ConditionalOnMissingBean(name = "oidcPrincipalFactory")
    @Bean
    @RefreshScope
    public PrincipalFactory oidcPrincipalFactory() {
        return PrincipalFactoryUtils.newPrincipalFactory();
    }

    @Bean
    @RefreshScope
    @ConditionalOnMissingBean(name = "oidcAttributeToScopeClaimMapper")
    public OidcAttributeToScopeClaimMapper oidcAttributeToScopeClaimMapper() {
        val mappings = casProperties.getAuthn().getOidc().getClaimsMap();
        return new OidcDefaultAttributeToScopeClaimMapper(mappings);
    }

    @Bean
    @RefreshScope
    public OAuth20ProfileScopeToAttributesFilter profileScopeToAttributesFilter() {
        return new OidcProfileScopeToAttributesFilter(oidcPrincipalFactory(),
            casProperties, userDefinedScopeBasedAttributeReleasePolicies());
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcServiceRegistryListener")
    public ServiceRegistryListener oidcServiceRegistryListener() {
        return new OidcServiceRegistryListener(userDefinedScopeBasedAttributeReleasePolicies());
    }

    @RefreshScope
    @Bean
    public OidcIntrospectionEndpointController oidcIntrospectionEndpointController() {
        val context = buildConfigurationContext();
        return new OidcIntrospectionEndpointController(context);
    }

    @RefreshScope
    @Bean
    public OidcLogoutEndpointController oidcLogoutEndpointController() {
        val context = buildConfigurationContext();
        return new OidcLogoutEndpointController(context);
    }

    @RefreshScope
    @Bean
    public OidcRevocationEndpointController oidcRevocationEndpointController() {
        val context = buildConfigurationContext();
        return new OidcRevocationEndpointController(context);
    }

    @RefreshScope
    @Bean
    public OidcAccessTokenEndpointController oidcAccessTokenController() {
        val context = buildConfigurationContext();
        return new OidcAccessTokenEndpointController(context);
    }

    @ConditionalOnMissingBean(name = "clientRegistrationRequestSerializer")
    @Bean
    @RefreshScope
    public StringSerializer<OidcClientRegistrationRequest> clientRegistrationRequestSerializer() {
        return new OidcClientRegistrationRequestSerializer();
    }

    @RefreshScope
    @Bean
    public OidcDynamicClientRegistrationEndpointController oidcDynamicClientRegistrationEndpointController() {
        val context = buildConfigurationContext();
        return new OidcDynamicClientRegistrationEndpointController(context);
    }

    @RefreshScope
    @Bean
    public OidcClientConfigurationEndpointController oidcClientConfigurationEndpointController() {
        val context = buildConfigurationContext();
        return new OidcClientConfigurationEndpointController(context);
    }

    @RefreshScope
    @Bean
    public OidcJwksEndpointController oidcJwksController() {
        val context = buildConfigurationContext();
        return new OidcJwksEndpointController(context, oidcJsonWebKeystoreGeneratorService());
    }

    @Autowired
    @RefreshScope
    @Bean
    public OidcWellKnownEndpointController oidcWellKnownController(@Qualifier("oidcServerDiscoverySettingsFactory") final OidcServerDiscoverySettings discoverySettings) {
        val context = buildConfigurationContext();
        return new OidcWellKnownEndpointController(
            context, new OidcWebFingerDiscoveryService(oidcWebFingerUserInfoRepository(), discoverySettings));
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcWebFingerUserInfoRepository")
    public OidcWebFingerUserInfoRepository oidcWebFingerUserInfoRepository() {
        val userInfo = casProperties.getAuthn().getOidc().getWebfinger().getUserInfo();

        if (userInfo.getGroovy().getLocation() != null) {
            return new OidcGroovyWebFingerUserInfoRepository(userInfo.getGroovy().getLocation());
        }

        if (StringUtils.isNotBlank(userInfo.getRest().getUrl())) {
            return new OidcRestfulWebFingerUserInfoRepository(userInfo.getRest());
        }

        LOGGER.warn("Using [{}] to locate webfinger resources, which is NOT appropriate for production purposes, "
            + "as it will always echo back the given username/email address and is only useful for testing/demo purposes. "
            + "Consider choosing and configuring a different repository implementation for locating and fetching user information "
            + "for webfinger resources, etc.", OidcEchoingWebFingerUserInfoRepository.class.getSimpleName());
        return new OidcEchoingWebFingerUserInfoRepository();
    }

    @RefreshScope
    @ConditionalOnMissingBean(name = "oidcProfileController")
    @Bean
    public OidcUserProfileEndpointController oidcProfileController() {
        val context = buildConfigurationContext();
        return new OidcUserProfileEndpointController(context);
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcUserProfileDataCreator")
    @RefreshScope
    public OAuth20UserProfileDataCreator oidcUserProfileDataCreator() {
        return new OidcUserProfileDataCreator(servicesManager.getObject(), profileScopeToAttributesFilter());
    }

    @RefreshScope
    @Bean
    public OidcAuthorizeEndpointController oidcAuthorizeController() {
        val context = buildConfigurationContext();
        return new OidcAuthorizeEndpointController(context);
    }

    @Bean
    @RefreshScope
    @ConditionalOnMissingBean(name = "oidcMultifactorAuthenticationTrigger")
    public MultifactorAuthenticationTrigger oidcMultifactorAuthenticationTrigger() {
        return new OidcMultifactorAuthenticationTrigger(casProperties, multifactorAuthenticationProviderResolver.getObject(), this.applicationContext);
    }

    @RefreshScope
    @Bean
    public CasWebflowEventResolver oidcAuthenticationContextWebflowEventResolver() {
        val context = CasWebflowEventResolutionConfigurationContext.builder()
            .authenticationSystemSupport(authenticationSystemSupport.getObject())
            .centralAuthenticationService(centralAuthenticationService.getObject())
            .servicesManager(servicesManager.getObject())
            .ticketRegistrySupport(ticketRegistrySupport.getObject())
            .warnCookieGenerator(warnCookieGenerator.getObject())
            .authenticationRequestServiceSelectionStrategies(authenticationRequestServiceSelectionStrategies.getObject())
            .registeredServiceAccessStrategyEnforcer(registeredServiceAccessStrategyEnforcer.getObject())
            .casProperties(casProperties)
            .ticketRegistry(ticketRegistry.getObject())
            .applicationContext(applicationContext)
            .build();

        val r = new DefaultMultifactorAuthenticationProviderWebflowEventResolver(context, oidcMultifactorAuthenticationTrigger());
        Objects.requireNonNull(this.initialAuthenticationAttemptWebflowEventResolver.getObject()).addDelegate(r);
        return r;
    }

    @ConditionalOnMissingBean(name = "oidcWebflowConfigurer")
    @Bean
    @DependsOn("defaultWebflowConfigurer")
    public CasWebflowConfigurer oidcWebflowConfigurer() {
        val cfg = new OidcWebflowConfigurer(flowBuilderServices.getObject(),
            loginFlowDefinitionRegistry.getObject(), oidcRegisteredServiceUIAction(), applicationContext, casProperties);
        cfg.setLogoutFlowDefinitionRegistry(logoutFlowDefinitionRegistry.getObject());
        return cfg;
    }

    @ConditionalOnMissingBean(name = "oidcRegisteredServiceUIAction")
    @Bean
    public Action oidcRegisteredServiceUIAction() {
        return new OidcRegisteredServiceUIAction(this.servicesManager.getObject(), oauth20AuthenticationServiceSelectionStrategy.getObject());
    }

    @Bean
    @RefreshScope
    @ConditionalOnMissingBean(name = "oidcTokenSigningAndEncryptionService")
    public OAuth20TokenSigningAndEncryptionService oidcTokenSigningAndEncryptionService() {
        val oidc = casProperties.getAuthn().getOidc();
        return new OidcIdTokenSigningAndEncryptionService(oidcDefaultJsonWebKeystoreCache(),
            oidcServiceJsonWebKeystoreCache(),
            oidc.getIssuer());
    }

    @Bean
    @RefreshScope
    @ConditionalOnMissingBean(name = "oidcUserProfileSigningAndEncryptionService")
    public OAuth20TokenSigningAndEncryptionService oidcUserProfileSigningAndEncryptionService() {
        val oidc = casProperties.getAuthn().getOidc();
        return new OidcUserProfileSigningAndEncryptionService(oidcDefaultJsonWebKeystoreCache(),
            oidcServiceJsonWebKeystoreCache(),
            oidc.getIssuer());
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcServiceJsonWebKeystoreCache")
    @RefreshScope
    public LoadingCache<OAuthRegisteredService, Optional<PublicJsonWebKey>> oidcServiceJsonWebKeystoreCache() {
        return Caffeine.newBuilder()
            .maximumSize(1)
            .expireAfter(new OidcServiceJsonWebKeystoreCacheExpirationPolicy(casProperties))
            .build(oidcServiceJsonWebKeystoreCacheLoader());
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcDefaultJsonWebKeystoreCache")
    @RefreshScope
    public LoadingCache<String, Optional<PublicJsonWebKey>> oidcDefaultJsonWebKeystoreCache() {
        val oidc = casProperties.getAuthn().getOidc();
        return Caffeine.newBuilder().maximumSize(1)
            .expireAfterWrite(Duration.ofMinutes(oidc.getJwks().getJwksCacheInMinutes()))
            .build(oidcDefaultJsonWebKeystoreCacheLoader());
    }

    @Bean
    @SneakyThrows
    @ConditionalOnMissingBean(name = "oidcDefaultJsonWebKeystoreCacheLoader")
    @RefreshScope
    public CacheLoader<String, Optional<PublicJsonWebKey>> oidcDefaultJsonWebKeystoreCacheLoader() {
        return new OidcDefaultJsonWebKeystoreCacheLoader(oidcJsonWebKeystoreGeneratorService());
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcServiceJsonWebKeystoreCacheLoader")
    public CacheLoader<OAuthRegisteredService, Optional<PublicJsonWebKey>> oidcServiceJsonWebKeystoreCacheLoader() {
        return new OidcServiceJsonWebKeystoreCacheLoader(applicationContext);
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcServerDiscoverySettingsFactory")
    public FactoryBean<OidcServerDiscoverySettings> oidcServerDiscoverySettingsFactory() {
        return new OidcServerDiscoverySettingsFactory(casProperties);
    }

    @Bean(initMethod = "generate")
    @RefreshScope
    @ConditionalOnMissingBean(name = "oidcJsonWebKeystoreGeneratorService")
    public OidcJsonWebKeystoreGeneratorService oidcJsonWebKeystoreGeneratorService() {
        val oidc = casProperties.getAuthn().getOidc();
        if (StringUtils.isNotBlank(oidc.getJwks().getRest().getUrl())) {
            return new OidcRestfulJsonWebKeystoreGeneratorService(oidc);
        }
        return new OidcDefaultJsonWebKeystoreGeneratorService(oidc);
    }

    @Bean
    public HandlerInterceptorAdapter oauthInterceptor() {
        val oidc = casProperties.getAuthn().getOidc();
        val mode = OidcConstants.DynamicClientRegistrationMode.valueOf(StringUtils.defaultIfBlank(
            oidc.getDynamicClientRegistrationMode(),
            OidcConstants.DynamicClientRegistrationMode.PROTECTED.name()));

        return new OidcHandlerInterceptorAdapter(requiresAuthenticationAccessTokenInterceptor.getObject(),
            requiresAuthenticationAuthorizeInterceptor(),
            requiresAuthenticationDynamicRegistrationInterceptor(),
            requiresAuthenticationClientConfigurationInterceptor(),
            mode,
            accessTokenGrantRequestExtractors.getObject(),
            servicesManager.getObject(),
            oauthDistributedSessionStore.getObject());
    }

    @RefreshScope
    @Bean
    public Collection<OidcCustomScopeAttributeReleasePolicy> userDefinedScopeBasedAttributeReleasePolicies() {
        val oidc = casProperties.getAuthn().getOidc();
        return oidc.getUserDefinedScopes().entrySet()
            .stream()
            .map(k -> new OidcCustomScopeAttributeReleasePolicy(k.getKey(), CollectionUtils.wrapList(k.getValue().split(","))))
            .collect(Collectors.toSet());
    }

    @Bean
    public OAuth20AuthorizationResponseBuilder oidcImplicitIdTokenCallbackUrlBuilder() {
        return new OidcImplicitIdTokenAuthorizationResponseBuilder(oidcIdTokenGenerator(), oauthTokenGenerator.getObject(),
            accessTokenExpirationPolicy.getObject(), grantingTicketExpirationPolicy.getObject(),
            servicesManager.getObject(), accessTokenJwtBuilder.getObject(), casProperties);
    }

    @Bean
    public OAuth20AuthorizationResponseBuilder oidcImplicitIdTokenAndTokenCallbackUrlBuilder() {
        return new OidcImplicitIdTokenAndTokenAuthorizationResponseBuilder(oidcIdTokenGenerator(), oauthTokenGenerator.getObject(),
            accessTokenExpirationPolicy.getObject(), grantingTicketExpirationPolicy.getObject(),
            servicesManager.getObject(), accessTokenJwtBuilder.getObject(), casProperties);
    }

    @Bean
    public RegisteredServiceCipherExecutor oauthRegisteredServiceJwtAccessTokenCipherExecutor() {
        val oidc = casProperties.getAuthn().getOidc();
        return new OidcRegisteredServiceJwtAccessTokenCipherExecutor(oidcDefaultJsonWebKeystoreCache(),
            oidcServiceJsonWebKeystoreCache(),
            oidc.getIssuer());
    }

    @Bean
    public OAuthAuthenticationClientProvider oidcClientConfigurationAuthenticationClientProvider() {
        return () -> {
            val accessTokenClient = new HeaderClient();
            accessTokenClient.setCredentialsExtractor(new BearerAuthExtractor());
            accessTokenClient.setAuthenticator(new OidcClientConfigurationAccessTokenAuthenticator(ticketRegistry.getObject(),
                accessTokenJwtBuilder.getObject()));
            accessTokenClient.setName(OidcConstants.CAS_OAUTH_CLIENT_CONFIG_ACCESS_TOKEN_AUTHN);
            accessTokenClient.init();
            return accessTokenClient;
        };
    }

    @Bean
    public OAuthAuthenticationClientProvider oidcPrivateKeyJwtClientProvider() {
        return () -> {
            val privateKeyJwtClient = new DirectFormClient(new OidcPrivateKeyJwtAuthenticator(
                servicesManager.getObject(),
                registeredServiceAccessStrategyEnforcer.getObject(),
                ticketRegistry.getObject(),
                webApplicationServiceFactory.getObject(),
                casProperties,
                applicationContext));
            privateKeyJwtClient.setName(OidcConstants.CAS_OAUTH_CLIENT_PRIVATE_KEY_JWT_AUTHN);
            privateKeyJwtClient.setUsernameParameter(OAuth20Constants.CLIENT_ASSERTION_TYPE);
            privateKeyJwtClient.setPasswordParameter(OAuth20Constants.CLIENT_ASSERTION);
            privateKeyJwtClient.init();
            return privateKeyJwtClient;
        };
    }

    @Bean
    public OAuthAuthenticationClientProvider oidcClientSecretJwtClientProvider() {
        return () -> {
            val client = new DirectFormClient(new OidcClientSecretJwtAuthenticator(
                servicesManager.getObject(),
                registeredServiceAccessStrategyEnforcer.getObject(),
                ticketRegistry.getObject(),
                webApplicationServiceFactory.getObject(),
                casProperties,
                applicationContext));
            client.setName(OidcConstants.CAS_OAUTH_CLIENT_CLIENT_SECRET_JWT_AUTHN);
            client.setUsernameParameter(OAuth20Constants.CLIENT_ASSERTION_TYPE);
            client.setPasswordParameter(OAuth20Constants.CLIENT_ASSERTION);
            client.init();
            return client;
        };
    }

    @Bean
    public Authenticator<TokenCredentials> oAuthAccessTokenAuthenticator() {
        return new OidcAccessTokenAuthenticator(ticketRegistry.getObject(),
            oidcTokenSigningAndEncryptionService(), servicesManager.getObject(),
            accessTokenJwtBuilder.getObject());
    }

    @ConditionalOnMissingBean(name = "oidcCasWebflowExecutionPlanConfigurer")
    @Bean
    public CasWebflowExecutionPlanConfigurer oidcCasWebflowExecutionPlanConfigurer() {
        return plan -> plan.registerWebflowConfigurer(oidcWebflowConfigurer());
    }

    @ConditionalOnMissingBean(name = "oidcUserProfileViewRenderer")
    @Bean
    @RefreshScope
    public OAuth20UserProfileViewRenderer oidcUserProfileViewRenderer() {
        return new OidcUserProfileViewRenderer(casProperties.getAuthn().getOauth(),
            servicesManager.getObject(),
            oidcUserProfileSigningAndEncryptionService());
    }

    @Bean
    public View oidcConfirmView() {
        return casProtocolViewFactory.getObject().create(applicationContext, "protocol/oidc/confirm");
    }

    @ConditionalOnMissingBean(name = "oidcSingleLogoutMessageCreator")
    @Bean
    @RefreshScope
    public SingleLogoutMessageCreator oidcSingleLogoutMessageCreator() {
        return new OidcSingleLogoutMessageCreator(buildConfigurationContext());
    }

    @ConditionalOnMissingBean(name = "oidcSingleLogoutServiceMessageHandler")
    @Bean
    @RefreshScope
    public SingleLogoutServiceMessageHandler oidcSingleLogoutServiceMessageHandler() {
        return new OidcSingleLogoutServiceMessageHandler(httpClient.getObject(),
            oidcSingleLogoutMessageCreator(),
            servicesManager.getObject(),
            singleLogoutServiceLogoutUrlBuilder.getObject(),
            casProperties.getSlo().isAsynchronous(),
            authenticationServiceSelectionPlan.getObject(),
            casProperties.getAuthn().getOidc().getIssuer());
    }

    @Bean
    @ConditionalOnMissingBean(name = "oidcLogoutExecutionPlanConfigurer")
    public LogoutExecutionPlanConfigurer oidcLogoutExecutionPlanConfigurer() {
        return plan -> plan.registerSingleLogoutServiceMessageHandler(oidcSingleLogoutServiceMessageHandler());
    }

    private OAuth20ConfigurationContext buildConfigurationContext() {
        return OAuth20ConfigurationContext.builder()
            .registeredServiceCipherExecutor(oauthRegisteredServiceCipherExecutor.getObject())
            .sessionStore(oauthDistributedSessionStore.getObject())
            .servicesManager(servicesManager.getObject())
            .ticketRegistry(ticketRegistry.getObject())
            .accessTokenFactory(defaultAccessTokenFactory.getObject())
            .deviceTokenFactory(defaultDeviceTokenFactory.getObject())
            .clientRegistrationRequestSerializer(clientRegistrationRequestSerializer())
            .clientIdGenerator(new DefaultRandomStringGenerator())
            .clientSecretGenerator(new DefaultRandomStringGenerator())
            .principalFactory(oidcPrincipalFactory())
            .webApplicationServiceServiceFactory(webApplicationServiceFactory.getObject())
            .casProperties(casProperties)
            .ticketGrantingTicketCookieGenerator(ticketGrantingTicketCookieGenerator.getObject())
            .resourceLoader(resourceLoader)
            .oauthConfig(oauthSecConfig.getObject())
            .registeredServiceAccessStrategyEnforcer(registeredServiceAccessStrategyEnforcer.getObject())
            .centralAuthenticationService(centralAuthenticationService.getObject())
            .callbackAuthorizeViewResolver(callbackAuthorizeViewResolver())
            .profileScopeToAttributesFilter(profileScopeToAttributesFilter())
            .accessTokenGenerator(oauthTokenGenerator.getObject())
            .accessTokenResponseGenerator(oidcAccessTokenResponseGenerator())
            .accessTokenExpirationPolicy(accessTokenExpirationPolicy.getObject())
            .deviceTokenExpirationPolicy(deviceTokenExpirationPolicy.getObject())
            .accessTokenGrantRequestValidators(oauthTokenRequestValidators.getObject())
            .accessTokenGrantAuditableRequestExtractor(accessTokenGrantAuditableRequestExtractor.getObject())
            .userProfileDataCreator(oidcUserProfileDataCreator())
            .userProfileViewRenderer(oidcUserProfileViewRenderer())
            .oAuthCodeFactory(defaultOAuthCodeFactory.getObject())
            .consentApprovalViewResolver(consentApprovalViewResolver())
            .authenticationBuilder(authenticationBuilder.getObject())
            .oauthAuthorizationResponseBuilders(oauthAuthorizationResponseBuilders.getObject())
            .oauthRequestValidators(oauthRequestValidators.getObject())
            .singleLogoutServiceLogoutUrlBuilder(singleLogoutServiceLogoutUrlBuilder.getObject())
            .idTokenSigningAndEncryptionService(oidcTokenSigningAndEncryptionService())
            .accessTokenJwtBuilder(accessTokenJwtBuilder.getObject())
            .build();
    }
}


text:
// Unit-test for DelayCache

#include "pagespeed/kernel/cache/delay_cache.h"

#include <cstddef>

#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/shared_string.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/util/platform.h"
#include "test/pagespeed/kernel/base/gtest.h"
#include "test/pagespeed/kernel/cache/cache_test_base.h"
#include "test/pagespeed/kernel/thread/worker_test_base.h"

namespace net_instaweb {
namespace {

const size_t kMaxSize = 100;

class DelayCacheTest : public CacheTestBase {
 protected:
  DelayCacheTest()
      : lru_cache_(kMaxSize),
        thread_system_(Platform::CreateThreadSystem()),
        cache_(&lru_cache_, thread_system_.get()) {}

  CacheInterface* Cache() override { return &cache_; }

 protected:
  LRUCache lru_cache_;
  std::unique_ptr<ThreadSystem> thread_system_;
  DelayCache cache_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DelayCacheTest);
};

TEST_F(DelayCacheTest, NoDelayOps) {
  // Basic operation w/o any delay injected.
  CheckNotFound("Name");
  CheckPut("Name", "Value");
  CheckGet("Name", "Value");
  cache_.Delete("Name");
  CheckNotFound("Name");
}

TEST_F(DelayCacheTest, DelayOpsFound) {
  // Load the value.
  CheckPut("Name", "Value");
  CheckPut("OtherName", "OtherValue");

  cache_.DelayKey("Name");
  cache_.DelayKey("OtherName");

  // Try getting...
  CacheTestBase::Callback result, other_result;
  cache_.Get("Name", &result);
  cache_.Get("OtherName", &other_result);

  // Initially, should not have been called.
  EXPECT_FALSE(result.called());

  // Release an unrelated key.  That should not call "Name".
  cache_.ReleaseKey("OtherName");
  EXPECT_FALSE(result.called());
  EXPECT_TRUE(other_result.called());
  EXPECT_EQ(CacheInterface::kAvailable, other_result.state());

  // Now after it is released, it should be OK.
  cache_.ReleaseKey("Name");
  EXPECT_TRUE(result.called());
  EXPECT_EQ(CacheInterface::kAvailable, result.state());
  EXPECT_EQ("Value", result.value().Value());
}

TEST_F(DelayCacheTest, DelayOpsNotFound) {
  // Do the same thing with a miss.
  cache_.DelayKey("Name");
  cache_.DelayKey("OtherName");
  CacheTestBase::Callback result, other_result;
  cache_.Get("Name", result.Reset());
  cache_.Get("OtherName", &other_result);
  EXPECT_FALSE(result.called());
  cache_.ReleaseKey("OtherName");
  EXPECT_FALSE(result.called());
  EXPECT_TRUE(other_result.called());
  EXPECT_EQ(CacheInterface::kNotFound, other_result.state());
  cache_.ReleaseKey("Name");
  EXPECT_TRUE(result.called());
  EXPECT_EQ(CacheInterface::kNotFound, result.state());
}

TEST_F(DelayCacheTest, DelayOpsFoundInSequence) {
  std::unique_ptr<ThreadSystem> thread_system(Platform::CreateThreadSystem());
  QueuedWorkerPool pool(1, "test", thread_system.get());
  QueuedWorkerPool::Sequence* sequence = pool.NewSequence();
  WorkerTestBase::SyncPoint sync_point(thread_system.get());

  // Load the value.
  CheckPut("Name", "Value");
  CheckPut("OtherName", "OtherValue");

  cache_.DelayKey("Name");
  cache_.DelayKey("OtherName");

  // Try getting...
  CacheTestBase::Callback result, other_result;
  cache_.Get("Name", &result);
  cache_.Get("OtherName", &other_result);

  // Initially, should not have been called.
  EXPECT_FALSE(result.called());

  // Release an unrelated key.  That should not call "Name".
  cache_.ReleaseKeyInSequence("OtherName", sequence);
  sequence->Add(new WorkerTestBase::NotifyRunFunction(&sync_point));
  sync_point.Wait();

  EXPECT_FALSE(result.called());
  EXPECT_TRUE(other_result.called());
  EXPECT_EQ(CacheInterface::kAvailable, other_result.state());

  // Now after it is released, it should be OK.
  cache_.ReleaseKey("Name");
  sequence->Add(new WorkerTestBase::NotifyRunFunction(&sync_point));
  sync_point.Wait();

  EXPECT_TRUE(result.called());
  EXPECT_EQ(CacheInterface::kAvailable, result.state());
  EXPECT_EQ("Value", result.value().Value());

  pool.ShutDown();
}

}  // namespace

}  // namespace net_instaweb

redpajama_set_name: RedPajamaGithub


text:
package com.intuit.ipp.exception;

import java.util.List;

import com.intuit.ipp.data.Error;

/**
 * Exception class to handle Invalid Request Error in HTTP Status code
 *
 */
public class InvalidRequestException extends FMSException {

	/**
	 * The Constant serialVersionUID.
	 */
	private static final long serialVersionUID = -2152752316496012401L;

	/**
	 * Constructor InvalidRequestException
	 *
	 * @param error the list of errors
	 */
	public InvalidRequestException(List<Error> error) {
		super(error);
	}

	/**
	 * Constructor InvalidRequestException
	 *
	 * @param errorMessage the error message
	 */
	public InvalidRequestException(String errorMessage) {
		super(errorMessage);
	}

	/**
	 * Constructor InvalidRequestException
	 *
	 * @param throwable the throwable
	 */
	public InvalidRequestException(Throwable throwable) {
		super(throwable);
	}

	/**
	 * Constructor InvalidRequestException
	 *
	 * @param errorMessage the error message
	 * @param throwable the throwable
	 */
	public InvalidRequestException(String errorMessage, Throwable throwable) {
		super(errorMessage, throwable);
	}
}


text:
import '#3p/polyfills';

import {register} from '#3p/3p';
import {draw3p, init} from '#3p/integration-lib';

import {polymorphicads} from '#ads/vendors/polymorphicads';

init(window);
register('polymorphicads', polymorphicads);

window.draw3p = draw3p;


text:
import csv
import arrow
import json

utc = arrow.utcnow()
local = utc.to('Europe/Prague')

with open('current.json', 'r') as jsn:
    cur = json.loads(jsn.read())

for item in cur:
    with open('data.csv', 'a') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow([item, cur[item]['pocet'],
                         cur[item]['zahajeni'], cur[item]['probihajici'],
                         local.format('YYYY-MM-DD')])


text:
solfege-bundle-sass
===================

SASS preprocessor for SolfegeJS


text:
export default class SupervisorModel {
  constructor (options) {
    this.id = options.id
    this.username = options.username
    this.rights = options.rights
  }
}


text: require('./spec/vendor/liquid.patch.js');


text:
package org.adligo.xml.parsers.template.jdbc;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * this is a postgres implementation
 *
 * this is not threadsafe!
 *
 * @author scott
 *
 */
public class DefaultPrettyQuery implements I_PrettyQuery {
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss");

	@Override
	public String prepairBoolean(Boolean p) {
		if (p) {
			return "1";
		} else {
			return "0";
		}
	}

	@Override
	public String prepairDate(Date p) {
		return "'" + sdf.format(p) + "'";
	}

	@Override
	public String prepairString(String p) {
		char [] ca = p.toCharArray();
	    String sR = new String();
	    for (int i = 0; i < ca.length; i++) {
	      if ( ca[i] == '\\') {
	        sR = sR + "\\\\";
	      } else if ( ca[i] == '\'') {
	        sR = sR + "\\'";
	      } else {
	        sR = sR + ca[i];
	      }
	    }
	    return sR;
	}

}


text:
(function() {
  'use strict';

  var el = d3.select('.punchcard'),
      margin = {top: 20, right: 20, bottom: 30, left: 80},
      elWidth = parseInt(el.style('width'), 10),
      elHeight = parseInt(el.style('height'), 10),
      width = elWidth - margin.left - margin.right,
      height = elHeight - margin.top - margin.bottom,
      padding = 20;

  var svg = el.append('svg')
      .attr('width', elWidth)
      .attr('height', elHeight)
    .append('g')
      .attr('transform', 'translate(' + margin.left + "," + margin.top + ')');

  d3.json('/data/punchcard.json', function(error, data) {
    visualize(data);
  });

  function visualize(data) {
    // code here
  }

}());


text:
package org.elasticsearch.common.recycler;

import com.carrotsearch.hppc.BitMixer;

import java.util.ArrayDeque;

public enum Recyclers {
    ;

    /**
     * Return a {@link Recycler} that never recycles entries.
     */
    public static <T> Recycler<T> none(Recycler.C<T> c) {
        return new NoneRecycler<>(c);
    }

    /**
     * Return a concurrent recycler based on a deque.
     */
    public static <T> Recycler<T> concurrentDeque(Recycler.C<T> c, int limit) {
        return new ConcurrentDequeRecycler<>(c, limit);
    }

    /**
     * Return a recycler based on a deque.
     */
    public static <T> Recycler<T> deque(Recycler.C<T> c, int limit) {
        return new DequeRecycler<>(c, new ArrayDeque<>(), limit);
    }

    /**
     * Return a recycler based on a deque.
     */
    public static <T> Recycler.Factory<T> dequeFactory(final Recycler.C<T> c, final int limit) {
        return () -> deque(c, limit);
    }

    /**
     * Wrap the provided recycler so that calls to {@link Recycler#obtain()} and {@link Recycler.V#close()} are protected by
     * a lock.
     */
    public static <T> Recycler<T> locked(final Recycler<T> recycler) {
        return new FilterRecycler<T>() {

            private final Object lock;

            {
                this.lock = new Object();
            }

            @Override
            protected Recycler<T> getDelegate() {
                return recycler;
            }

            @Override
            public Recycler.V<T> obtain() {
                synchronized (lock) {
                    return super.obtain();
                }
            }

            @Override
            protected Recycler.V<T> wrap(final Recycler.V<T> delegate) {
                return new Recycler.V<T>() {

                    @Override
                    public void close() {
                        synchronized (lock) {
                            delegate.close();
                        }
                    }

                    @Override
                    public T v() {
                        return delegate.v();
                    }

                    @Override
                    public boolean isRecycled() {
                        return delegate.isRecycled();
                    }

                };
            }

        };
    }

    /**
     * Create a concurrent implementation that can support concurrent access from
     * concurrencyLevel threads with little contention.
     */
    public static <T> Recycler<T> concurrent(final Recycler.Factory<T> factory, final int concurrencyLevel) {
        if (concurrencyLevel < 1) {
            throw new IllegalArgumentException("concurrencyLevel must be >= 1");
        }
        if (concurrencyLevel == 1) {
            return locked(factory.build());
        }
        return new FilterRecycler<T>() {

            private final Recycler<T>[] recyclers;

            {
                @SuppressWarnings("unchecked")
                final Recycler<T>[] recyclers = new Recycler[concurrencyLevel];
                this.recyclers = recyclers;
                for (int i = 0; i < concurrencyLevel; ++i) {
                    recyclers[i] = locked(factory.build());
                }
            }

            int slot() {
                final long id = Thread.currentThread().getId();
                // don't trust Thread.hashCode to have equiprobable low bits
                int slot = (int) BitMixer.mix64(id);
                // make positive, otherwise % may return negative numbers
                slot &= 0x7FFFFFFF;
                slot %= concurrencyLevel;
                return slot;
            }

            @Override
            protected Recycler<T> getDelegate() {
                return recyclers[slot()];
            }

        };
    }

    public static <T> Recycler<T> concurrent(final Recycler.Factory<T> factory) {
        return concurrent(factory, Runtime.getRuntime().availableProcessors());
    }
}


text:
package com.grum.geocalc;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import static org.junit.Assert.*;

@RunWith(JUnit4.class)
/**
 * @see http://www.csgnetwork.com/gpscoordconv.html for online converter
 */
public class CoordinateTest {

    @Test
    public void testDegreeCoordinate() {
        DegreeCoordinate degreeCoordinate = new DegreeCoordinate(90);
        Coordinate coordinate = degreeCoordinate.getDegreeCoordinate();
        assertEquals(degreeCoordinate.decimalDegrees, coordinate.decimalDegrees, 1E-4);

        DMSCoordinate dmsCoordinate = new DMSCoordinate(44, 37, 14);
        degreeCoordinate = new DegreeCoordinate(44.620555555555555);
        assertEquals(degreeCoordinate.decimalDegrees, dmsCoordinate.decimalDegrees, 1E-4);
    }

    @Test
    public void testRadianCoordinate() {
        RadianCoordinate radianCoordinate = new RadianCoordinate(Math.PI / 2);
        Coordinate coordinate = radianCoordinate.getDegreeCoordinate();
        assertEquals(radianCoordinate.decimalDegrees, coordinate.decimalDegrees, 1E-4);

        radianCoordinate = new RadianCoordinate(Math.PI * .57);
        DegreeCoordinate degreeCoordinate = new DegreeCoordinate(180 * .57);
        assertEquals(degreeCoordinate.decimalDegrees, radianCoordinate.decimalDegrees, 1E-4);

        DegreeCoordinate convertedBackDegreeCoordinate = radianCoordinate.getDegreeCoordinate();
        assertEquals(degreeCoordinate.decimalDegrees, convertedBackDegreeCoordinate.decimalDegrees, 1E-4);

        DMSCoordinate dmsCoordinate = new DMSCoordinate(44, 37, 14);
        radianCoordinate = new RadianCoordinate(Math.toRadians(44.620555555555555));
        assertEquals(radianCoordinate.decimalDegrees, dmsCoordinate.decimalDegrees, 1E-4);
    }

    @Test
    public void testDMSCoordinate() {
        DMSCoordinate dmsCoordinate = new DMSCoordinate(89, 59, 60.45);
        Coordinate coordinate = dmsCoordinate.getDegreeCoordinate();
        assertEquals(dmsCoordinate.decimalDegrees, coordinate.decimalDegrees, 1E-5);

        dmsCoordinate = new DMSCoordinate(175, 8, 55.45);
        DegreeCoordinate degreeCoordinate = new DegreeCoordinate(175.14873);
        assertEquals(degreeCoordinate.decimalDegrees, dmsCoordinate.decimalDegrees, 1E-5);

        DegreeCoordinate convertedBackDegreeCoordinate = dmsCoordinate.getDegreeCoordinate();
        assertEquals(degreeCoordinate.decimalDegrees, convertedBackDegreeCoordinate.decimalDegrees, 1E-5);

        RadianCoordinate radianCoordinate = new RadianCoordinate(Math.PI * 3 / 2);
        dmsCoordinate = new DMSCoordinate(270, 0, 0);
        assertEquals(radianCoordinate.getDMSCoordinate().decimalDegrees, dmsCoordinate.decimalDegrees, 1E-5);
    }

    @Test
    public void testDMSCoordinateNegativeValue() {
        DMSCoordinate dmsCoordinate = new DMSCoordinate(-46, 32, 44.16);
        assertEquals(-46.5456, dmsCoordinate.decimalDegrees, 0);

        DegreeCoordinate degreeCoordinate = new DegreeCoordinate(-46.5456);
        dmsCoordinate = degreeCoordinate.getDMSCoordinate();
        assertEquals(-46, dmsCoordinate.getWholeDegrees(), 0);
        assertEquals(32, dmsCoordinate.getMinutes(), 0);
        assertEquals(44.16, dmsCoordinate.getSeconds(), 0);
    }

    @Test
    public void testGPSCoordinate() {
        GPSCoordinate gpsCoordinate = new GPSCoordinate(89, 60);
        Coordinate coordinate = gpsCoordinate.getDegreeCoordinate();
        assertEquals(gpsCoordinate.decimalDegrees, coordinate.decimalDegrees, 1E-4);

        gpsCoordinate = new GPSCoordinate(175, 8.921999999999457);
        DegreeCoordinate degreeCoordinate = new DegreeCoordinate(175.1487);
        assertEquals(degreeCoordinate.decimalDegrees, gpsCoordinate.decimalDegrees, 1E-4);

        DegreeCoordinate convertedBackDegreeCoordinate = gpsCoordinate.getDegreeCoordinate();
        assertEquals(degreeCoordinate.decimalDegrees, convertedBackDegreeCoordinate.decimalDegrees, 1E-4);

        RadianCoordinate radianCoordinate = new RadianCoordinate(Math.PI * 3 / 2);
        gpsCoordinate = new GPSCoordinate(270, 0);
        assertEquals(radianCoordinate.getDMSCoordinate().decimalDegrees, gpsCoordinate.decimalDegrees, 1E-4);
    }

    @Test
    public void testIsContainedWithin() {
        Point northEast = new Point(new DegreeCoordinate(70), new DegreeCoordinate(145));
        Point southWest = new Point(new DegreeCoordinate(50), new DegreeCoordinate(110));
        BoundingArea boundingArea = new BoundingArea(northEast, southWest);

        Point point1 = new Point(new DegreeCoordinate(60), new DegreeCoordinate(120));
        assertTrue(boundingArea.isContainedWithin(point1));

        Point point2 = new Point(new DegreeCoordinate(45), new DegreeCoordinate(120));
        assertFalse(boundingArea.isContainedWithin(point2));

        Point point3 = new Point(new DegreeCoordinate(85), new DegreeCoordinate(120));
        assertFalse(boundingArea.isContainedWithin(point3));

        Point point4 = new Point(new DegreeCoordinate(60), new DegreeCoordinate(100));
        assertFalse(boundingArea.isContainedWithin(point4));

        Point point5 = new Point(new DegreeCoordinate(60), new DegreeCoordinate(150));
        assertFalse(boundingArea.isContainedWithin(point5));

        Point point6 = new Point(new DegreeCoordinate(80), new DegreeCoordinate(150));
        assertFalse(boundingArea.isContainedWithin(point6));

        Point point7 = new Point(new DegreeCoordinate(35), new DegreeCoordinate(100));
        assertFalse(boundingArea.isContainedWithin(point7));

        northEast = new Point(new DegreeCoordinate(10), new DegreeCoordinate(45));
        southWest = new Point(new DegreeCoordinate(-30), new DegreeCoordinate(-35));
        boundingArea = new BoundingArea(northEast, southWest);

        Point point8 = new Point(new DegreeCoordinate(0), new DegreeCoordinate(0));
        assertTrue(boundingArea.isContainedWithin(point8));

        Point point9 = new Point(new DegreeCoordinate(-5), new DegreeCoordinate(-30));
        assertTrue(boundingArea.isContainedWithin(point9));

        Point point10 = new Point(new DegreeCoordinate(5), new DegreeCoordinate(30));
        assertTrue(boundingArea.isContainedWithin(point10));

        Point point11 = new Point(new DegreeCoordinate(-35), new DegreeCoordinate(30));
        assertFalse(boundingArea.isContainedWithin(point11));

        northEast = new Point(new DegreeCoordinate(10), new DegreeCoordinate(-165));
        southWest = new Point(new DegreeCoordinate(-30), new DegreeCoordinate(170));
        boundingArea = new BoundingArea(northEast, southWest);

        Point point12 = new Point(new DegreeCoordinate(0), new DegreeCoordinate(180));
        assertTrue(boundingArea.isContainedWithin(point12));

        Point point13 = new Point(new DegreeCoordinate(0), new DegreeCoordinate(-179));
        assertTrue(boundingArea.isContainedWithin(point13));
    }

    @Test
    public void testConvertingToSelf() {
        GPSCoordinate gpsCoordinate = new GPSCoordinate(89, 60);
        assertEquals(gpsCoordinate.getGPSCoordinate().decimalDegrees, gpsCoordinate.decimalDegrees, 10E-5);

        DegreeCoordinate degreeCoordinate = new DegreeCoordinate(-46.5456);
        assertEquals(degreeCoordinate.getDegreeCoordinate().decimalDegrees, degreeCoordinate.decimalDegrees, 10E-5);

        DMSCoordinate dmsCoordinate = new DMSCoordinate(89, 59, 60.45);
        assertEquals(dmsCoordinate.getDMSCoordinate().decimalDegrees, dmsCoordinate.decimalDegrees, 10E-5);

        RadianCoordinate radianCoordinate = new RadianCoordinate(Math.PI / 2);
        assertEquals(radianCoordinate.getRadianCoordinate().decimalDegrees, radianCoordinate.decimalDegrees, 10E-5);
    }
}


text:
package ru.job4j;

import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;

/**.
 * Task 7.3.2.
 * Create User Storage
 *
 * @author Anton Vasilyuk on 27.07.2017.
 * @version 1.0.
 */
public class UserStorage {

    /**.
     * @storage is structure for data about the users
     */
    private Map<Integer, User> storage;

    /**.
     * Constructor for this class
     */
    public UserStorage() {
        storage = new HashMap<>();
    }

    /**.
     * Method for add this user to the structure
     * @param user is user for adding
     */
    public void add(User user) {
        synchronized (this) {
            if (user != null && !storage.containsKey(user.getId())) {
                storage.put(user.getId(), user);
            } else {
                return;
            }
        }
    }

    /**.
     * Method for update data about the user
     * @param id user to update
     * @param amount is change amount the user
     */
    public void update(Integer id, int amount) {
        synchronized (this) {
            if (storage.get(id) != null && amount != 0 && storage.containsKey(id)) {
                if (!storage.containsKey(id)) {
                    new NoSuchElementException("This id no registered");
                }
                int newAmount = storage.get(id).getAmount() + amount;
                User user = storage.get(id);
                user.setAmount(newAmount);
                storage.put(id, user);
            } else {
                return;
            }
        }
    }

    /**.
     * Method for delete user from this structure
     * @param id is id from search this user
     */
    public void delete(Integer id) {
        synchronized (this) {
            if (id != null && storage.containsKey(id)) {
                storage.remove(id);
            } else {
                return;
            }
        }
    }

    /**.
     * Method for transfer money from first user account to second user account
     * @param fromId the user who transfer
     * @param toId the user which trahsfer
     * @param amount is the amount of money
     */
    public void transfer(Integer fromId, Integer toId, int amount) {
        synchronized (this) {
            if (storage.get(fromId).getAmount() < amount) {
                System.out.printf("The user has insufficient funds");
                return;
            }

            if (!storage.containsKey(fromId) || !storage.containsKey(toId)) {
                new NoSuchElementException("This id no registered");
            }

            int amountForFromUser = 0 - amount;
            int amountForToUser = amount;

            update(fromId, amountForFromUser);
            update(toId, amountForToUser);

            if (storage.get(fromId).getAmount() == 0) {
                delete(fromId);
            }
        }
    }

    /**.
     * The method for checking change in this the data structure
     * @return storage
     */
    public Map<Integer, User> getStorage() {
        synchronized (this) {
            return this.storage;
        }
    }

}


text:
<!DOCTYPE html>

            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                ×
            </button>

            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                ×
            </button>

    <form data-th-action="@{__${action}__}"
          data-th-object="${user}"
          method="get"
          class="form-horizontal"
          id="formData">

        <input type="hidden" name="_method" data-th-value="${method}" data-th-if="${method != null}"/>

        <input type="hidden"
               id="plan"
               name="plan" />

        <input type="hidden"
               id="kit"
               name="kit" />

                                <button type="button"
                                        class="btn btn-theme btn-upgrade-now"
                                        data-th-text="#{users.plan.btn.upgrade}">
                                    Atualizar Agora
                                </button>
                                <input type="hidden" data-th-value="${plan.value}"/>

Title

Question?

Price

Explanation.

Kit Content

Item 1

Item 2

Item 3

Item 4

                                <input class="form-control input-price"
                                       type="number"
                                       id="quantityKit"
                                       name="quantityKit"
                                       min="1"
                                       value="1"/>

                                <button type="button" id="buyKit" class="btn btn-primary btn-top" data-th-text="#{users.plan.modal.btn_buy}">Buy kit</button>

                                <button type="button" id="noKit" data-dismiss="modal" aria-hidden="true" class="btn btn-primary pull-left btn-top" data-th-text=#{users.plan.modal.btn_not_buy}>Without kit</button>

Text footer

    </form>


text:
package org.openqa.selenium.server.htmlrunner;

import org.openqa.selenium.BuildInfo;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;

public class Results {

  private final String suiteSource;
  private final List<String> allTables = new LinkedList<>();
  private final List<Boolean> allResults = new LinkedList<>();
  private final StringBuilder log = new StringBuilder();
  private final long start = System.currentTimeMillis();

  private boolean succeeded = true;
  private long numberOfPasses;
  private long commandPasses;
  private long commandFailures;
  private long commandErrors;

  public Results(String suiteSource) {
    this.suiteSource = suiteSource;
  }

  public boolean isSuccessful() {
    return succeeded;
  }

  public void addTest(String rawSource, List<CoreTestCase.StepResult> stepResults) {
    boolean passed = true;
    for (CoreTestCase.StepResult stepResult : stepResults) {
      passed &= stepResult.isSuccessful();
      if (stepResult.isSuccessful()) {
        commandPasses++;
      } else if (stepResult.isError()) {
        commandErrors++;
      } else {
        commandFailures++;
      }

      log.append(stepResult.getStepLog()).append("\n");
    }

    if (passed) {
      numberOfPasses++;
    }
    succeeded &= passed;

    allTables.add(
      massage(rawSource, "insert-core-result", stepResults, input -> input.getRenderableClass()));
    allResults.add(passed);
  }

  private <X> String massage(
    String rawSource,
    String toSubstitute,
    List<X> toConvert,
    Function<X, String> transform) {

    Reader stringReader = new StringReader(rawSource);
    HTMLEditorKit htmlKit = new HTMLEditorKit();
    HTMLDocument doc = (HTMLDocument) htmlKit.createDefaultDocument();
    HTMLEditorKit.Parser parser = doc.getParser();
    doc.setAsynchronousLoadPriority(-1);
    ElementCallback callback;
    try {
      callback = new ElementCallback(
        toSubstitute,
        toConvert.stream().map(transform).iterator());
      parser.parse(stringReader, callback, true);
    } catch (IOException e) {
      throw new RuntimeException("Unable to parse test table");
    }

    StringBuilder sb = new StringBuilder();
    int previousPosition = rawSource.length();
    for (int i = callback.tagPositions.size() - 1; i >= 0; i--) {
      int pos = callback.tagPositions.get(i);
      String toReplace = callback.originals.get(i);
      String substitution = callback.substitutions.get(i);
      String snippet = rawSource.substring(pos, previousPosition).replace('\\', '/');
      String replaceSnippet = snippet.replaceFirst("\\Q" + toReplace + "\\E", substitution);
      sb.insert(0, replaceSnippet);
      previousPosition = pos;
    }
    String snippet = rawSource.substring(0, previousPosition);
    sb.insert(0, snippet);

    return sb.toString();
  }

  public HTMLTestResults toSuiteResult() {
    BuildInfo buildInfo = new BuildInfo();

    return new HTMLTestResults(
      buildInfo.getReleaseLabel(),
      buildInfo.getBuildRevision(),
      isSuccessful() ? "PASS" : "FAIL",
      String.valueOf(System.currentTimeMillis() - start),
      String.valueOf(allTables.size()),
      String.valueOf(numberOfPasses),
      String.valueOf(allTables.size() - numberOfPasses),
      String.valueOf(commandPasses),
      String.valueOf(commandFailures),
      String.valueOf(commandErrors),
      massage(
        suiteSource,
        "insert-test-result",
        allResults,
        input -> input ? "status_passed" : "status_failed"),
      allTables,
      log.toString());
  }

  private static class ElementCallback extends HTMLEditorKit.ParserCallback {
    private final String toSubstitute;
    private final List<Integer> tagPositions = new LinkedList<>();
    private final List<String> originals = new LinkedList<>();
    private final List<String> substitutions = new LinkedList<>();
    private final Iterator<String> allResults;

    public ElementCallback(String toSubstitute, Iterator<String> allResults) {
      this.toSubstitute = toSubstitute;
      this.allResults = allResults;
    }

    @Override
    public void handleStartTag(HTML.Tag tag, MutableAttributeSet attrs, int pos) {
      if (allResults.hasNext() && HTML.Tag.TR.equals(tag)) {
        Object rawAttr = attrs.getAttribute(HTML.Attribute.CLASS);
        if (rawAttr != null) {
          String classes = String.valueOf(rawAttr);
          if (classes.contains(toSubstitute)) {
            String result = allResults.next();
            originals.add(classes);
            substitutions.add(classes.replace(toSubstitute, result));
            tagPositions.add(pos);
          }
        }
      }
    }
  }
}