// Path: src/main/java/ltistarter/config/ApplicationConfig.java
// @Component
// public class ApplicationConfig implements ApplicationContextAware {
// 
//     final static Logger log = LoggerFactory.getLogger(ApplicationConfig.class);
//     private volatile static ApplicationContext context;
//     private volatile static ApplicationConfig config;
// 
//     @Autowired
//     ConfigurableEnvironment env;
// 
//     @Resource(name = "defaultConversionService")
//     @SuppressWarnings("SpringJavaAutowiringInspection")
//     ConversionService conversionService;
// 
//     @Autowired
//     @SuppressWarnings("SpringJavaAutowiringInspection")
//     ConfigRepository configRepository;
// 
//     @PostConstruct
//     public void init() {
//         log.info("INIT");
//         //log.info("profiles active: " + ArrayUtils.toString(env.getActiveProfiles()));
//         //log.info("profiles default: " + ArrayUtils.toString(env.getDefaultProfiles()));
//         env.setActiveProfiles("dev", "testing");
//         config = this;
//         log.info("Config INIT: profiles active: " + ArrayUtils.toString(env.getActiveProfiles()));
//     }
// 
//     @PreDestroy
//     public void shutdown() {
//         context = null;
//         config = null;
//         log.info("DESTROY");
//     }
// 
//     // DELEGATED from the spring Environment (easier config access)
// 
//     public ConfigurableEnvironment getEnvironment() {
//         return env;
//     }
// 
//     /**
//      * Return whether the given property key is available for resolution, i.e.,
//      * the value for the given key is not {@code null}.
//      */
//     public boolean containsProperty(String key) {
//         assert key != null;
//         boolean contains = env.containsProperty(key);
//         if (!contains) {
//             ConfigEntity ce = configRepository.findByName(key);
//             contains = (ce != null);
//         }
//         return contains;
//     }
// 
//     /**
//      * Return the property value associated with the given key, or
//      * {@code defaultValue} if the key cannot be resolved.
//      *
//      * @param key          the property name to resolve
//      * @param defaultValue the default value to return if no value is found
//      */
//     public String getProperty(String key, String defaultValue) {
//         return getProperty(key, String.class, defaultValue);
//     }
// 
//     /**
//      * Return the property value associated with the given key, or
//      * {@code defaultValue} if the key cannot be resolved.
//      *
//      * @param key          the property name to resolve
//      * @param targetType   the expected type of the property value
//      * @param defaultValue the default value to return if no value is found
//      */
//     public <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
//         assert key != null;
//         assert targetType != null;
//         T property = env.getProperty(key, targetType, defaultValue);
//         // check for database override
//         ConfigEntity ce = configRepository.findByName(key);
//         if (ce != null) {
//             try {
//                 property = conversionService.convert(ce.getValue(), targetType);
//             } catch (Exception e) {
//                 property = defaultValue;
//                 log.warn("Failed to convert config (" + ce.getValue() + ") into a (" + targetType + "), using default (" + defaultValue + "): " + e);
//             }
//         }
//         return property;
//     }
// 
//     @Override
//     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//         context = applicationContext;
//     }
// 
//     /**
//      * @return the current service instance the spring application context (only populated after init)
//      */
//     public static ApplicationContext getContext() {
//         return context;
//     }
// 
//     /**
//      * @return the current service instance of the config object (only populated after init)
//      */
//     public static ApplicationConfig getInstance() {
//         return config;
//     }
// 
// }


import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import ltistarter.config.ApplicationConfig;
import ltistarter.model.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
    /**
     * Checks if we have a valid tool registration in the current request
     *
     * @return true if valid, false otherwise
     * @throws IllegalArgumentException if the inputs are invalid
     * @throws IllegalStateException    is the key request is not approved or valid
     */
    public boolean checkValidToolRegistration() {
        assert ltiDataService != null;
        // See if current user is allowed to register a tool
        KeyRequestEntity keyRequestEntity = ltiDataService.findKeyRequest(this);

        if (keyRequestEntity == null) {
            throw new IllegalStateException("Cannot find a key request for the current user");
        }
        if (keyRequestEntity.getState() == 0) {
            throw new IllegalStateException("Your key has not yet been approved");
        }
        if (keyRequestEntity.getState() != 1) {
            throw new IllegalStateException("Your key request was not approved");
        }
        if (keyRequestEntity.getLti() != 2) {
            throw new IllegalStateException("You did not request an LTI 2.0 key");
        }
        // We have a person authorized to use LTI 2.0 on this server

        String regKey;
        String regPass;
        if (LTI_MESSAGE_TYPE_PROXY_REREG.equals(this.ltiMessageType)) {
            regKey = this.ltiConsumerKey;
// Path: src/main/java/ltistarter/config/ApplicationConfig.java
// @Component
// public class ApplicationConfig implements ApplicationContextAware {
// 
//     final static Logger log = LoggerFactory.getLogger(ApplicationConfig.class);
//     private volatile static ApplicationContext context;
//     private volatile static ApplicationConfig config;
// 
//     @Autowired
//     ConfigurableEnvironment env;
// 
//     @Resource(name = "defaultConversionService")
//     @SuppressWarnings("SpringJavaAutowiringInspection")
//     ConversionService conversionService;
// 
//     @Autowired
//     @SuppressWarnings("SpringJavaAutowiringInspection")
//     ConfigRepository configRepository;
// 
//     @PostConstruct
//     public void init() {
//         log.info("INIT");
//         //log.info("profiles active: " + ArrayUtils.toString(env.getActiveProfiles()));
//         //log.info("profiles default: " + ArrayUtils.toString(env.getDefaultProfiles()));
//         env.setActiveProfiles("dev", "testing");
//         config = this;
//         log.info("Config INIT: profiles active: " + ArrayUtils.toString(env.getActiveProfiles()));
//     }
// 
//     @PreDestroy
//     public void shutdown() {
//         context = null;
//         config = null;
//         log.info("DESTROY");
//     }
// 
//     // DELEGATED from the spring Environment (easier config access)
// 
//     public ConfigurableEnvironment getEnvironment() {
//         return env;
//     }
// 
//     /**
//      * Return whether the given property key is available for resolution, i.e.,
//      * the value for the given key is not {@code null}.
//      */
//     public boolean containsProperty(String key) {
//         assert key != null;
//         boolean contains = env.containsProperty(key);
//         if (!contains) {
//             ConfigEntity ce = configRepository.findByName(key);
//             contains = (ce != null);
//         }
//         return contains;
//     }
// 
//     /**
//      * Return the property value associated with the given key, or
//      * {@code defaultValue} if the key cannot be resolved.
//      *
//      * @param key          the property name to resolve
//      * @param defaultValue the default value to return if no value is found
//      */
//     public String getProperty(String key, String defaultValue) {
//         return getProperty(key, String.class, defaultValue);
//     }
// 
//     /**
//      * Return the property value associated with the given key, or
//      * {@code defaultValue} if the key cannot be resolved.
//      *
//      * @param key          the property name to resolve
//      * @param targetType   the expected type of the property value
//      * @param defaultValue the default value to return if no value is found
//      */
//     public <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
//         assert key != null;
//         assert targetType != null;
//         T property = env.getProperty(key, targetType, defaultValue);
//         // check for database override
//         ConfigEntity ce = configRepository.findByName(key);
//         if (ce != null) {
//             try {
//                 property = conversionService.convert(ce.getValue(), targetType);
//             } catch (Exception e) {
//                 property = defaultValue;
//                 log.warn("Failed to convert config (" + ce.getValue() + ") into a (" + targetType + "), using default (" + defaultValue + "): " + e);
//             }
//         }
//         return property;
//     }
// 
//     @Override
//     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//         context = applicationContext;
//     }
// 
//     /**
//      * @return the current service instance the spring application context (only populated after init)
//      */
//     public static ApplicationContext getContext() {
//         return context;
//     }
// 
//     /**
//      * @return the current service instance of the config object (only populated after init)
//      */
//     public static ApplicationConfig getInstance() {
//         return config;
//     }
// 
// }


// Path: src/main/java/ltistarter/lti/LTIRequest.java
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import ltistarter.config.ApplicationConfig;
import ltistarter.model.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

    /**
     * Checks if we have a valid tool registration in the current request
     *
     * @return true if valid, false otherwise
     * @throws IllegalArgumentException if the inputs are invalid
     * @throws IllegalStateException    is the key request is not approved or valid
     */
    public boolean checkValidToolRegistration() {
        assert ltiDataService != null;
        // See if current user is allowed to register a tool
        KeyRequestEntity keyRequestEntity = ltiDataService.findKeyRequest(this);

        if (keyRequestEntity == null) {
            throw new IllegalStateException("Cannot find a key request for the current user");
        }
        if (keyRequestEntity.getState() == 0) {
            throw new IllegalStateException("Your key has not yet been approved");
        }
        if (keyRequestEntity.getState() != 1) {
            throw new IllegalStateException("Your key request was not approved");
        }
        if (keyRequestEntity.getLti() != 2) {
            throw new IllegalStateException("You did not request an LTI 2.0 key");
        }
        // We have a person authorized to use LTI 2.0 on this server

        String regKey;
        String regPass;
        if (LTI_MESSAGE_TYPE_PROXY_REREG.equals(this.ltiMessageType)) {
            regKey = this.ltiConsumerKey;
            regPass = "secret";