
com.stormpath.sdk.servlet.application.DefaultApplicationResolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of stormpath-sdk-servlet Show documentation
Show all versions of stormpath-sdk-servlet Show documentation
Servlet-specific additions allowing one to more easily deploy the Stormpath SDK in a servlet-container-based
web application.
The newest version!
/*
* Copyright 2015 Stormpath, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stormpath.sdk.servlet.application;
import com.stormpath.sdk.application.Application;
import com.stormpath.sdk.application.ApplicationList;
import com.stormpath.sdk.client.Client;
import com.stormpath.sdk.client.PairedApiKey;
import com.stormpath.sdk.impl.application.OktaApplication;
import com.stormpath.sdk.impl.ds.InternalDataStore;
import com.stormpath.sdk.impl.error.DefaultError;
import com.stormpath.sdk.lang.Assert;
import com.stormpath.sdk.mail.EmailService;
import com.stormpath.sdk.resource.ResourceException;
import com.stormpath.sdk.servlet.client.DefaultServletContextClientFactory;
import com.stormpath.sdk.servlet.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @since 1.0.RC3
*/
public class DefaultApplicationResolver implements ApplicationResolver {
public static final Logger LOG = LoggerFactory.getLogger(DefaultApplicationResolver.class);
public static final String STORMPATH_APPLICATION_HREF = DefaultServletContextClientFactory.STORMPATH_APPLICATION_HREF;
private static final String APP_HREF_ERROR =
"The application's stormpath.properties configuration does not have a " + STORMPATH_APPLICATION_HREF +
" property defined. This property is required when looking up an application by ServletContext and " +
"you have more than one application registered in Stormpath. For example:\n\n" +
" # in stormpath.properties:\n" +
" " + STORMPATH_APPLICATION_HREF + " = YOUR_STORMPATH_APPLICATION_HREF_HERE\n";
protected Client getClient(ServletContext sc) {
Client client = (Client) sc.getAttribute(Client.class.getName());
Assert.notNull(client, "Stormpath Client instance is not available in the ServletContext. Ensure the " +
"ClientLoaderListener is defined before the ApplicationLoaderListener.");
return client;
}
protected Config getConfig(ServletContext servletContext) {
Config config = (Config) servletContext.getAttribute(Config.class.getName());
Assert.notNull(config, "Stormpath Config instance is not available in the ServletContext. Ensure the " +
"ConfigLoaderListener is defined before the ApplicationLoaderListener.");
return config;
}
@Override
public Application getApplication(final ServletRequest servletRequest) {
Object attribute = servletRequest.getAttribute(Application.class.getName());
if (attribute != null) {
Assert.isInstanceOf(Application.class, attribute);
return (Application) attribute;
}
return getApplication(servletRequest.getServletContext());
}
@Override
public Application getApplication(final ServletContext servletContext) {
Assert.notNull(servletContext, "ServletContext argument cannot be null.");
//see if it has been added to the servlet context yet:
Object attribute = servletContext.getAttribute(Application.class.getName());
if (attribute != null) {
Assert.isInstanceOf(Application.class, attribute);
return (Application) attribute;
}
//otherwise we have to do a lookup via the client and cache the result in the app context:
//get the client:
Client client = getClient(servletContext);
Config config = getConfig(servletContext);
if (Boolean.valueOf(config.get("okta.enabled"))) {
try {
EmailService emailService = config.getInstance("stormpath.email.service");
Map oktaAppConfigMap = new LinkedHashMap<>();
oktaAppConfigMap.put(OktaApplication.AUTHORIZATION_SERVER_ID_KEY, config.getOktaAuthorizationServerId());
oktaAppConfigMap.put(OktaApplication.EMAIL_SERVICE_KEY, emailService);
oktaAppConfigMap.put(OktaApplication.REGISTRATION_WORKFLOW_KEY, Boolean.valueOf(config.get("stormpath.registration.workflow.enabled")));
oktaAppConfigMap.put(OktaApplication.CLIENT_KEY, client);
oktaAppConfigMap.put(OktaApplication.ALLOW_API_SECRET, config.isAllowApiSecret());
oktaAppConfigMap.put(OktaApplication.USER_API_QUERY_TEMPLATE, config.getUserApiQueryTemplate());
oktaAppConfigMap.put(OktaApplication.APPLICATION_ID, config.get("okta.application.id"));
oktaAppConfigMap.put(OktaApplication.PASSWORD_POLICY_NAME, config.get("okta.password.policy.name"));
oktaAppConfigMap.put(OktaApplication.APPLICATION_GROUP_ID, config.get("okta.application.groupId"));
// TODO: There must be a better way to get the clientId
OktaApplication oktaApplication = new OktaApplication(((PairedApiKey)client.getApiKey()).getSecondaryApiKey().getId(),
(InternalDataStore) client.getDataStore());
oktaApplication.configureWithProperties(oktaAppConfigMap);
return oktaApplication;
} catch (ServletException e) {
LOG.error("Failed to configure EmailService", e);
throw new ResourceException(new DefaultError()
.setCode(500)
.setMessage("Failed to resolve Application")
.setDeveloperMessage(e.getMessage()));
}
}
//this is a local cached href value that we use in case we have to query applications (see below):
String href = (String) servletContext.getAttribute(STORMPATH_APPLICATION_HREF);
if (href == null) {
//no cached value = try config:
href = config.get(STORMPATH_APPLICATION_HREF);
}
Application application;
if (href == null) {
//no stormpath.application.href property was configured. Let's try to find their application:
ApplicationList apps = client.getApplications();
Application single = null;
for (Application app : apps) {
if (app.getName().equalsIgnoreCase("Stormpath")) { //ignore the admin app
continue;
}
if (single != null) {
//there is more than one application in the tenant, and we can't infer which one should be used
//for this particular application. Let them know:
throw new IllegalStateException(APP_HREF_ERROR);
}
single = app;
}
if (single != null) {
//save the href for later so we don't have to query the collection again:
servletContext.setAttribute(STORMPATH_APPLICATION_HREF, single.getHref());
}
application = single;
} else {
Assert.hasText(href, "The specified " + STORMPATH_APPLICATION_HREF + " property value cannot be empty.");
//now lookup the app (will be cached when caching is turned on in the SDK):
try {
application = client.getResource(href, Application.class);
} catch (Exception e) {
String msg = "Unable to lookup Stormpath application reference by " + STORMPATH_APPLICATION_HREF +
" [" + href + "]. Please ensure this href is accurate and reflects an application " +
"registered in Stormpath.";
throw new IllegalArgumentException(msg, e);
}
}
//cache for future lookups:
servletContext.setAttribute(Application.class.getName(), application);
return application;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy