Created
October 26, 2011 16:28
-
-
Save dsyer/1316904 to your computer and use it in GitHub Desktop.
Dave Syer: Demos for s2gx2011
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
target/ | |
*/src/main/*/META-INF/ | |
.access_token | |
.result | |
.classpath | |
.project | |
.DS_Store | |
.settings/ | |
*.iml | |
*.iws | |
*.ipr | |
.idea/ | |
cargo-installs/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beansProjectDescription> | |
<version>1</version> | |
<pluginVersion><![CDATA[2.8.0.201110170010-RELEASE]]></pluginVersion> | |
<configSuffixes> | |
<configSuffix><![CDATA[xml]]></configSuffix> | |
</configSuffixes> | |
<enableImports><![CDATA[false]]></enableImports> | |
<configs> | |
<config>src/main/webapp/WEB-INF/spring-servlet.xml</config> | |
</configs> | |
<configSets> | |
</configSets> | |
</beansProjectDescription> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beansProjectDescription> | |
<version>1</version> | |
<pluginVersion><![CDATA[2.6.0.201104111100-PATCH]]></pluginVersion> | |
<configSuffixes> | |
<configSuffix><![CDATA[xml]]></configSuffix> | |
</configSuffixes> | |
<enableImports><![CDATA[false]]></enableImports> | |
<configs> | |
<config>src/main/webapp/WEB-INF/spring-servlet.xml</config> | |
</configs> | |
<configSets> | |
</configSets> | |
</beansProjectDescription> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beansProjectDescription> | |
<version>1</version> | |
<pluginVersion><![CDATA[2.8.0.201110170010-RELEASE]]></pluginVersion> | |
<configSuffixes> | |
<configSuffix><![CDATA[xml]]></configSuffix> | |
</configSuffixes> | |
<enableImports><![CDATA[false]]></enableImports> | |
<configs> | |
<config>src/main/webapp/WEB-INF/spring-servlet.xml</config> | |
</configs> | |
<configSets> | |
</configSets> | |
</beansProjectDescription> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beansProjectDescription> | |
<version>1</version> | |
<pluginVersion><![CDATA[2.6.0.201104111100-PATCH]]></pluginVersion> | |
<configSuffixes> | |
<configSuffix><![CDATA[xml]]></configSuffix> | |
</configSuffixes> | |
<enableImports><![CDATA[false]]></enableImports> | |
<configs> | |
<config>src/main/webapp/WEB-INF/spring-servlet.xml</config> | |
</configs> | |
<configSets> | |
</configSets> | |
</beansProjectDescription> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ taglib prefix="authz" | |
uri="http://www.springframework.org/security/tags"%> | |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | |
<title>Sparklr</title> | |
<link type="text/css" rel="stylesheet" | |
href="<c:url value="/resources/style.css"/>" /> | |
</head> | |
<body> | |
<h1>OAuth2 Authorization</h1> | |
<div id="content"> | |
<c:if test="${error}"> | |
<div class="error"> | |
<h2>Woops!</h2> | |
<p>${error}</p> | |
</div> | |
</c:if> | |
<authz:authorize ifAllGranted="ROLE_USER"> | |
<h2>Please Confirm</h2> | |
<p>Do you authorize ${client.clientId} to access your protected | |
resources in scope ${auth_request.scope}.</p> | |
<form id="confirmationForm" name="confirmationForm" | |
action="${options.confirm.location}" method="POST"> | |
<input name="${options.confirm.key}" | |
value="${options.confirm.value}" type="hidden" /> <label><input | |
name="authorize" value="Authorize" type="submit"> | |
</label> | |
</form> | |
<form id="denialForm" name="denialForm" | |
action="${options.deny.location}" method="POST"> | |
<input name="${options.deny.key}" value="${options.deny.value}" | |
type="hidden" /> <label><input name="deny" value="Deny" | |
type="submit"> | |
</label> | |
</form> | |
</authz:authorize> | |
</div> | |
<div id="footer">Demo only</div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.uaa.web; | |
import java.security.Principal; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.LinkedHashMap; | |
import java.util.Map; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpSession; | |
import org.cloudfoundry.identity.uaa.web.OpenIdProviderController.Openid; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.security.oauth2.provider.AuthorizationRequest; | |
import org.springframework.security.oauth2.provider.ClientDetails; | |
import org.springframework.security.oauth2.provider.ClientDetailsService; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.web.bind.annotation.ModelAttribute; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.RequestMethod; | |
import org.springframework.web.bind.annotation.SessionAttributes; | |
import org.springframework.web.context.request.WebRequest; | |
/** | |
* Controller for retrieving the model for and displaying the confirmation page for access to a protected resource. | |
* | |
* @author Ryan Heaton | |
* @author Dave Syer | |
*/ | |
@Controller | |
@SessionAttributes(types = AuthorizationRequest.class) | |
public class AccessController { | |
private ClientDetailsService clientDetailsService; | |
@ModelAttribute("identity") | |
public String getIdentity(HttpSession session) { | |
Openid openid = (Openid) session.getAttribute("openid"); | |
return openid == null ? null : openid.getIdentity(); | |
} | |
@RequestMapping("/oauth/confirm_access") | |
public String confirm(@ModelAttribute AuthorizationRequest clientAuth, Map<String, Object> model, final HttpServletRequest request) | |
throws Exception { | |
if (clientAuth == null) { | |
model.put( | |
"error", | |
"No client authentication token is present in the request, so we cannot confirm access (we don't know what you are asking for)."); | |
// response.sendError(HttpServletResponse.SC_BAD_REQUEST); | |
} | |
else { | |
ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); | |
model.put("auth_request", clientAuth); | |
model.put("client", client); | |
model.put("message", | |
"To confirm or deny access POST to the following locations with the parameters requested."); | |
Map<String, Object> options = new HashMap<String, Object>() { | |
{ | |
put("confirm", new HashMap<String, String>() { | |
{ | |
put("location", getLocation(request, "oauth/authorize")); | |
put("key", "user_oauth_approval"); | |
put("value", "true"); | |
} | |
}); | |
put("deny", new HashMap<String, String>() { | |
{ | |
put("location", getLocation(request, "oauth/authorize")); | |
put("key", "user_oauth_approval"); | |
put("value", "false"); | |
} | |
}); | |
} | |
}; | |
model.put("options", options); | |
} | |
return "access_confirmation"; | |
} | |
@RequestMapping(value = "/login", method = RequestMethod.GET) | |
public String defaultLoginPage(Map<String, Object> model, final WebRequest request) { | |
String username = ""; | |
if (model.containsKey("claimed_identity")) { | |
String identity = (String) model.get("claimed_identity"); | |
username = extractUserName(identity); | |
} | |
model.put("username", username); | |
model.put( | |
"message", | |
"You are logged out. Please POST to the location provided with form parameters according to the type of client you are."); | |
Map<String, Object> options = new HashMap<String, Object>() { | |
{ | |
put("shell", new HashMap<String, Object>() { | |
{ | |
put("location", getLocation(request, "oauth/token")); | |
put("parameters", Arrays.asList("username", "password", "grant_type=password", "client_id")); | |
} | |
}); | |
put("browser", new HashMap<String, Object>() { | |
{ | |
put("location", getLocation(request, "login.do")); | |
put("parameters", getPrompts()); | |
} | |
}); | |
} | |
}; | |
model.put("options", options); | |
return "login"; | |
} | |
private String extractUserName(String identity) { | |
if (identity == null) { | |
return ""; | |
} | |
String[] split = identity.split("/"); | |
return split.length == 1 ? identity : split[split.length - 1]; | |
} | |
@RequestMapping(value = { "/", "/home" }) | |
public String homePage(Map<String, Object> model, WebRequest request, Principal principal) { | |
Object error = request.getAttribute("SPRING_SECURITY_403_EXCEPTION", WebRequest.SCOPE_REQUEST); | |
if (error != null) { | |
model.put("error", "You don't have access to this resource (" + error + ")"); | |
} | |
model.put("message", "You are logged in. Log out by sending a GET to the location provided."); | |
model.put("location", "http:" + request.getHeader("Host") + request.getContextPath() + "/logout.do"); | |
model.put("principal", principal); | |
return "home"; | |
} | |
private Map<String, String[]> getPrompts() { | |
Map<String, String[]> prompts = new LinkedHashMap<String, String[]>(); | |
prompts.put("username", new String[] { "text", "Username" }); | |
prompts.put("password", new String[] { "hidden", "Password" }); | |
return prompts; | |
} | |
@Autowired | |
public void setClientDetailsService(ClientDetailsService clientDetailsService) { | |
this.clientDetailsService = clientDetailsService; | |
} | |
private String getLocation(HttpServletRequest request, String path) { | |
return "http://" + request.getHeader("Host") + request.getContextPath() + "/" + path; | |
} | |
private String getLocation(WebRequest request, String path) { | |
return "http://" + request.getHeader("Host") + request.getContextPath() + "/" + path; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.uaa.util; | |
import java.io.File; | |
import java.io.IOException; | |
import org.apache.commons.io.FileUtils; | |
import org.springframework.beans.BeansException; | |
import org.springframework.beans.factory.BeanInitializationException; | |
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; | |
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class ApacheDsCleanup implements BeanFactoryPostProcessor { | |
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { | |
try { | |
FileUtils.deleteDirectory(new File(System.getProperty("java.io.tmpdir"), "apacheds-spring-security")); | |
} catch (IOException e) { | |
throw new BeanInitializationException("Cannot clear Apache DS directory"); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
auth.url=http://dsyerauth.cloudfoundry.com/login | |
jdbc.driver=org.hsqldb.jdbcDriver | |
# jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true | |
# use this one for a separate server process so you can inspect the results | |
# (or add it to system properties with -D to override at run time). | |
jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples | |
jdbc.user=sa | |
jdbc.password= | |
jdbc.testWhileIdle=false | |
jdbc.validationQuery= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
openidProviderUrl=http://dsyerauth.cloudfoundry.com/openid | |
photoListUrl=http://dsyerapi.cloudfoundry.com/photos | |
photoUrlPattern=http://dsyerapp.cloudfoundry.com/photos/%s | |
photoUrlPassthruPattern=http://dsyerapi.cloudfoundry.com/photos/%s | |
accessTokenUri=http://dsyerauth.cloudfoundry.com/oauth/token | |
userAuthorizationUri=http://dsyerauth.cloudfoundry.com/oauth/authorize | |
jdbc.driver= | |
jdbc.url= | |
jdbc.user= | |
jdbc.password= | |
jdbc.testWhileIdle=false | |
jdbc.validationQuery= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
openidProviderUrl=http://dsyerauth.cloudfoundry.com/openid | |
photoListUrl=http://dsyerapi.cloudfoundry.com/photos | |
photoUrlPattern=http://dsyerapp.cloudfoundry.com/photos/%s | |
photoUrlPassthruPattern=http://dsyerapi.cloudfoundry.com/photos/%s | |
accessTokenUri=http://dsyerauth.cloudfoundry.com/oauth/token | |
userAuthorizationUri=http://dsyerauth.cloudfoundry.com/oauth/authorize | |
jdbc.driver= | |
jdbc.url= | |
jdbc.user= | |
jdbc.password= | |
jdbc.testWhileIdle=false | |
jdbc.validationQuery= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
auth.url=http://localhost:8080/auth/login | |
jdbc.driver=org.hsqldb.jdbcDriver | |
# jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true | |
# use this one for a separate server process so you can inspect the results | |
# (or add it to system properties with -D to override at run time). | |
jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples | |
jdbc.user=sa | |
jdbc.password= | |
jdbc.testWhileIdle=false | |
jdbc.validationQuery= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
openidProviderUrl=http://localhost:8080/auth/openid | |
# openidProviderUrl=https://www.google.com/accounts/o8/id | |
photoListUrl=http://localhost:8080/api/photos | |
photoUrlPattern=http://localhost:8080/app/photos/%s | |
photoUrlPassthruPattern=http://localhost:8080/api/photos/%s | |
accessTokenUri=http://localhost:8080/auth/oauth/token | |
userAuthorizationUri=http://localhost:8080/auth/oauth/authorize |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jdbc.driver=org.hsqldb.jdbcDriver | |
# jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true | |
# use this one for a separate server process so you can inspect the results | |
# (or add it to system properties with -D to override at run time). | |
jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples | |
jdbc.user=sa | |
jdbc.password= | |
jdbc.testWhileIdle=false | |
jdbc.validationQuery= | |
endpointUrl=http://localhost:8080/auth/openid/provider |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
openidProviderUrl=http://localhost:8080/auth/openid | |
# openidProviderUrl=https://www.google.com/accounts/o8/id |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.app.web; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertNotNull; | |
import static org.junit.Assert.assertTrue; | |
import java.net.URI; | |
import java.util.Arrays; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.util.LinkedMultiValueMap; | |
import org.springframework.util.MultiValueMap; | |
/** | |
* @author Dave Syer | |
*/ | |
public class ApplicationIntegrationTests { | |
@Rule | |
public ServerRunning serverRunning = ServerRunning.isRunning(); | |
/** | |
* tests the basic implicit provider | |
*/ | |
@Test | |
public void testBasicHomePage() throws Exception { | |
HttpHeaders appHeaders = new HttpHeaders(); | |
appHeaders.setAccept(Arrays.asList(MediaType.ALL)); | |
URI uri = serverRunning.buildUri("/app/").build(); | |
ResponseEntity<Void> result = serverRunning.getForResponse(uri.toString(), appHeaders); | |
assertEquals(HttpStatus.FOUND, result.getStatusCode()); | |
String location = result.getHeaders().getLocation().toString(); | |
String cookie = result.getHeaders().getFirst("Set-Cookie"); | |
assertNotNull("Expected cookie in " + result.getHeaders(), cookie); | |
appHeaders.set("Cookie", cookie); | |
// redirect to /openid | |
assertTrue(location.contains("/app/login")); | |
result = serverRunning.getForResponse(location, appHeaders); | |
assertEquals(HttpStatus.FOUND, result.getStatusCode()); | |
location = result.getHeaders().getLocation().toString(); | |
// redirect to /auth | |
HttpHeaders authHeaders = new HttpHeaders(); | |
authHeaders.setAccept(Arrays.asList(MediaType.ALL)); | |
// redirect to /auth/openid/provider | |
assertTrue(location.contains("/openid/provider")); | |
result = serverRunning.getForResponse(location, authHeaders); | |
assertEquals(HttpStatus.FOUND, result.getStatusCode()); | |
location = result.getHeaders().getLocation().toString(); | |
// redirect to /auth/openid/authorize | |
assertTrue(location.contains("/openid/authorize")); | |
result = serverRunning.getForResponse(location, authHeaders); | |
assertEquals(HttpStatus.FOUND, result.getStatusCode()); | |
location = result.getHeaders().getLocation().toString(); | |
// redirect to /auth/login | |
assertTrue(location.contains("/login")); | |
ResponseEntity<String> response = serverRunning.getForString(location, authHeaders); | |
// should be directed to the login screen... | |
assertTrue(response.getBody().contains("auth/login.do")); | |
assertTrue(response.getBody().contains("username")); | |
assertTrue(response.getBody().contains("password")); | |
location = "/auth/login.do"; | |
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); | |
formData.add("username", "marissa"); | |
formData.add("password", "koala"); | |
response = serverRunning.postForPage(location, authHeaders, formData); | |
// should be directed to the approval screen... | |
assertTrue(response.getBody().contains("auth/openid/authorize")); | |
assertTrue(response.getBody().contains("approve")); | |
location = "/auth/openid/authorize"; | |
formData = new LinkedMultiValueMap<String, String>(); | |
formData.add("approve", "Approve"); | |
// The cookie was set in the postForPage above (when we authenticated) | |
assertTrue(authHeaders.containsKey("Cookie")); | |
result = serverRunning.postForRedirect(location, authHeaders, formData); | |
assertNotNull(result.getHeaders().getLocation()); | |
location = result.getHeaders().getLocation().toString(); | |
// redirect to /app/j_spring_openid_security_check | |
assertTrue(location.contains("/app/login")); | |
result = serverRunning.getForResponse(location, appHeaders); | |
assertEquals(HttpStatus.FOUND, result.getStatusCode()); | |
location = result.getHeaders().getLocation().toString(); | |
response = serverRunning.getForString(location, appHeaders); | |
assertTrue("Wrong response: " + response.getBody(), response.getBody().contains("Sample Home Page")); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.api.web; | |
import org.junit.Test; | |
import org.springframework.context.support.GenericXmlApplicationContext; | |
import org.springframework.core.io.FileSystemResource; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class BootstrapTests { | |
@Test | |
public void testRootContext() throws Exception { | |
GenericXmlApplicationContext context = new GenericXmlApplicationContext(new FileSystemResource( | |
"src/main/webapp/WEB-INF/spring-servlet.xml")); | |
context.close(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import org.junit.Test; | |
import org.springframework.context.support.GenericXmlApplicationContext; | |
import org.springframework.core.io.FileSystemResource; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class BootstrapTests { | |
@Test | |
public void testRootContext() throws Exception { | |
GenericXmlApplicationContext context = new GenericXmlApplicationContext(new FileSystemResource("src/main/webapp/WEB-INF/spring-servlet.xml")); | |
context.close(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.uaa.web; | |
import java.io.File; | |
import java.io.IOException; | |
import org.apache.commons.io.FileUtils; | |
import org.junit.After; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.springframework.context.support.GenericXmlApplicationContext; | |
import org.springframework.core.io.FileSystemResource; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class BootstrapTests { | |
@After | |
@Before | |
public void close() throws IOException { | |
FileUtils.deleteDirectory(new File(System.getProperty("java.io.tmpdir"), "apacheds-spring-security")); | |
} | |
@Test | |
public void testRootContext() throws Exception { | |
GenericXmlApplicationContext context = new GenericXmlApplicationContext(new FileSystemResource("src/main/webapp/WEB-INF/spring-servlet.xml")); | |
context.close(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import org.junit.Test; | |
import org.springframework.context.support.GenericXmlApplicationContext; | |
import org.springframework.core.io.FileSystemResource; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class BootstrapTests { | |
@Test | |
public void testRootContext() throws Exception { | |
GenericXmlApplicationContext context = new GenericXmlApplicationContext(new FileSystemResource("src/main/webapp/WEB-INF/spring-servlet.xml")); | |
context.close(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2002-2011 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.api.web.mvc; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class CompositeFilter implements Filter { | |
private List<Filter> filters = new ArrayList<Filter>(); | |
public void setFilters(List<Filter> filters) { | |
this.filters = new ArrayList<Filter>(filters); | |
} | |
public void destroy() { | |
for (Filter filter : filters) { | |
filter.destroy(); | |
} | |
} | |
public void init(FilterConfig config) throws ServletException { | |
for (Filter filter : filters) { | |
filter.init(config); | |
} | |
} | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, | |
ServletException { | |
new VirtualFilterChain(chain, filters).doFilter(request, response); | |
} | |
private static class VirtualFilterChain implements FilterChain { | |
private final FilterChain originalChain; | |
private final List<Filter> additionalFilters; | |
private int currentPosition = 0; | |
private VirtualFilterChain(FilterChain chain, List<Filter> additionalFilters) { | |
this.originalChain = chain; | |
this.additionalFilters = additionalFilters; | |
} | |
public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { | |
if (currentPosition == additionalFilters.size()) { | |
originalChain.doFilter(request, response); | |
} else { | |
currentPosition++; | |
Filter nextFilter = additionalFilters.get(currentPosition - 1); | |
nextFilter.doFilter(request, response, this); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
drop table oauth_access_token; | |
drop table oauth_refresh_token; | |
create table oauth_access_token ( | |
token_id VARCHAR(256), | |
token BLOB, | |
authentication BLOB, | |
refresh_token VARCHAR(256) | |
); | |
create table oauth_refresh_token ( | |
token_id VARCHAR(256), | |
token BLOB, | |
authentication BLOB | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
drop table oauth_access_token; | |
drop table oauth_refresh_token; | |
create table oauth_access_token ( | |
token_id VARCHAR(256), | |
token LONGVARBINARY, | |
authentication LONGVARBINARY, | |
refresh_token VARCHAR(256) | |
); | |
create table oauth_refresh_token ( | |
token_id VARCHAR(256), | |
token LONGVARBINARY, | |
authentication LONGVARBINARY | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.openid.user; | |
import java.util.Collection; | |
import org.springframework.security.core.GrantedAuthority; | |
import org.springframework.security.core.userdetails.User; | |
/** | |
* Customized {@code UserDetails} implementation. | |
* | |
* @author Luke Taylor | |
* @since 3.1 | |
*/ | |
public class CustomUserDetails extends User { | |
private String email; | |
private String name; | |
private boolean newUser; | |
public CustomUserDetails(String username, Collection<GrantedAuthority> authorities) { | |
super(username, "unused", authorities); | |
} | |
public String getEmail() { | |
return email; | |
} | |
public void setEmail(String email) { | |
this.email = email; | |
} | |
public boolean isNewUser() { | |
return newUser; | |
} | |
public void setNewUser(boolean newUser) { | |
this.newUser = newUser; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.openid.user; | |
import java.util.Collection; | |
import org.springframework.security.core.GrantedAuthority; | |
import org.springframework.security.core.userdetails.User; | |
/** | |
* Customized {@code UserDetails} implementation. | |
* | |
* @author Luke Taylor | |
* @since 3.1 | |
*/ | |
public class CustomUserDetails extends User { | |
private String email; | |
private String name; | |
private boolean newUser; | |
public CustomUserDetails(String username, Collection<GrantedAuthority> authorities) { | |
super(username, "unused", authorities); | |
} | |
public String getEmail() { | |
return email; | |
} | |
public void setEmail(String email) { | |
this.email = email; | |
} | |
public boolean isNewUser() { | |
return newUser; | |
} | |
public void setNewUser(boolean newUser) { | |
this.newUser = newUser; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.openid.user; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import org.springframework.security.core.GrantedAuthority; | |
import org.springframework.security.core.authority.AuthorityUtils; | |
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; | |
import org.springframework.security.core.userdetails.UserDetails; | |
import org.springframework.security.core.userdetails.UserDetailsService; | |
import org.springframework.security.core.userdetails.UsernameNotFoundException; | |
import org.springframework.security.openid.OpenIDAttribute; | |
import org.springframework.security.openid.OpenIDAuthenticationToken; | |
/** | |
* Custom UserDetailsService which accepts any OpenID user, "registering" new users in a map so they can be welcomed | |
* back to the site on subsequent logins. | |
* | |
* @author Luke Taylor | |
* @since 3.1 | |
*/ | |
public class CustomUserDetailsService implements UserDetailsService, AuthenticationUserDetailsService<OpenIDAuthenticationToken> { | |
private final Map<String, CustomUserDetails> registeredUsers = new HashMap<String, CustomUserDetails>(); | |
private static final List<GrantedAuthority> DEFAULT_AUTHORITIES = AuthorityUtils.createAuthorityList("ROLE_USER"); | |
/** | |
* Implementation of {@code UserDetailsService}. We only need this to satisfy the {@code RememberMeServices} | |
* requirements. | |
*/ | |
public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException { | |
UserDetails user = registeredUsers.get(id); | |
if (user == null) { | |
throw new UsernameNotFoundException(id); | |
} | |
return user; | |
} | |
/** | |
* Implementation of {@code AuthenticationUserDetailsService} which allows full access to the submitted | |
* {@code Authentication} object. Used by the OpenIDAuthenticationProvider. | |
*/ | |
public UserDetails loadUserDetails(OpenIDAuthenticationToken token) { | |
String id = token.getIdentityUrl(); | |
CustomUserDetails user = registeredUsers.get(id); | |
if (user != null) { | |
return user; | |
} | |
String email = null; | |
String firstName = null; | |
String lastName = null; | |
String fullName = null; | |
List<OpenIDAttribute> attributes = token.getAttributes(); | |
for (OpenIDAttribute attribute : attributes) { | |
if (attribute.getName().equals("email")) { | |
email = attribute.getValues().get(0); | |
} | |
if (attribute.getName().equals("firstname")) { | |
firstName = attribute.getValues().get(0); | |
} | |
if (attribute.getName().equals("lastname")) { | |
lastName = attribute.getValues().get(0); | |
} | |
if (attribute.getName().equals("fullname")) { | |
fullName = attribute.getValues().get(0); | |
} | |
} | |
if (fullName == null) { | |
StringBuilder fullNameBldr = new StringBuilder(); | |
if (firstName != null) { | |
fullNameBldr.append(firstName); | |
} | |
if (lastName != null) { | |
fullNameBldr.append(" ").append(lastName); | |
} | |
fullName = fullNameBldr.toString(); | |
} | |
user = new CustomUserDetails(id, DEFAULT_AUTHORITIES); | |
user.setEmail(email); | |
user.setName(fullName); | |
registeredUsers.put(id, user); | |
user = new CustomUserDetails(id, DEFAULT_AUTHORITIES); | |
user.setEmail(email); | |
user.setName(fullName); | |
user.setNewUser(true); | |
return user; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.openid.user; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import org.springframework.security.core.GrantedAuthority; | |
import org.springframework.security.core.authority.AuthorityUtils; | |
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; | |
import org.springframework.security.core.userdetails.UserDetails; | |
import org.springframework.security.core.userdetails.UserDetailsService; | |
import org.springframework.security.core.userdetails.UsernameNotFoundException; | |
import org.springframework.security.openid.OpenIDAttribute; | |
import org.springframework.security.openid.OpenIDAuthenticationToken; | |
/** | |
* Custom UserDetailsService which accepts any OpenID user, "registering" new users in a map so they can be welcomed | |
* back to the site on subsequent logins. | |
* | |
* @author Luke Taylor | |
* @since 3.1 | |
*/ | |
public class CustomUserDetailsService implements UserDetailsService, AuthenticationUserDetailsService<OpenIDAuthenticationToken> { | |
private final Map<String, CustomUserDetails> registeredUsers = new HashMap<String, CustomUserDetails>(); | |
private static final List<GrantedAuthority> DEFAULT_AUTHORITIES = AuthorityUtils.createAuthorityList("ROLE_USER"); | |
/** | |
* Implementation of {@code UserDetailsService}. We only need this to satisfy the {@code RememberMeServices} | |
* requirements. | |
*/ | |
public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException { | |
UserDetails user = registeredUsers.get(id); | |
if (user == null) { | |
throw new UsernameNotFoundException(id); | |
} | |
return user; | |
} | |
/** | |
* Implementation of {@code AuthenticationUserDetailsService} which allows full access to the submitted | |
* {@code Authentication} object. Used by the OpenIDAuthenticationProvider. | |
*/ | |
public UserDetails loadUserDetails(OpenIDAuthenticationToken token) { | |
String id = token.getIdentityUrl(); | |
CustomUserDetails user = registeredUsers.get(id); | |
if (user != null) { | |
return user; | |
} | |
String email = null; | |
String firstName = null; | |
String lastName = null; | |
String fullName = null; | |
List<OpenIDAttribute> attributes = token.getAttributes(); | |
for (OpenIDAttribute attribute : attributes) { | |
if (attribute.getName().equals("email")) { | |
email = attribute.getValues().get(0); | |
} | |
if (attribute.getName().equals("firstname")) { | |
firstName = attribute.getValues().get(0); | |
} | |
if (attribute.getName().equals("lastname")) { | |
lastName = attribute.getValues().get(0); | |
} | |
if (attribute.getName().equals("fullname")) { | |
fullName = attribute.getValues().get(0); | |
} | |
} | |
if (fullName == null) { | |
StringBuilder fullNameBldr = new StringBuilder(); | |
if (firstName != null) { | |
fullNameBldr.append(firstName); | |
} | |
if (lastName != null) { | |
fullNameBldr.append(" ").append(lastName); | |
} | |
fullName = fullNameBldr.toString(); | |
} | |
user = new CustomUserDetails(id, DEFAULT_AUTHORITIES); | |
user.setEmail(email); | |
user.setName(fullName); | |
registeredUsers.put(id, user); | |
user = new CustomUserDetails(id, DEFAULT_AUTHORITIES); | |
user.setEmail(email); | |
user.setName(fullName); | |
user.setNewUser(true); | |
return user; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
<body> | |
<h1>OpenID Sample Home Page (Photos)</h1> | |
<p> | |
Welcome<c:if test="${!principal.principal.newUser}"> back,</c:if> ${principal.principal.name} | |
</p> | |
<c:if test="${principal.principal.newUser}"> | |
<p> | |
As a first time user of this site, your OpenID identity has been registered | |
by the application and will be recognized if you return. | |
</p> | |
</c:if> | |
<h3>Technical Information</h3> | |
<p> | |
Your principal object is....: ${principal} | |
</p> | |
<ul> | |
<li><a href="photos">Photos</a></li> | |
<li><a href="<c:url value="/"/>">Home</a></li> | |
<li><a href="j_spring_security_logout">Logout</a></li> | |
</ul> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ taglib prefix="authz" uri="http://www.springframework.org/security/tags" %> | |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |
<title>Authorization Server Home</title> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
<body> | |
<h1>Authorization Server</h1> | |
<div id="content"> | |
<h2>Home</h2> | |
<p>This is test page to ensure that your account login is working.</p> | |
<c:if test="${error}" > | |
<div class="error"> | |
<h2>Woops!</h2> | |
<p>${error}</p> | |
</div> | |
</c:if> | |
<authz:authorize ifNotGranted="ROLE_USER"> | |
<h2>You are logged in but do not have the user role</h2> | |
<div>You should never see this, but if you do, maybe you can <a href="<c:url value="/login"/>">log in here</a></div> | |
<br/> | |
</authz:authorize> | |
<authz:authorize ifAllGranted="ROLE_USER"> | |
<h2>You are logged in</h2> | |
</authz:authorize> | |
<div style="text-align: center"><form action="<c:url value="/logout.do"/>"><input type="submit" value="Logout"/></form></div> | |
</div> | |
<div id="footer">Demo only</div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
</head> | |
<body> | |
<h1>OpenID Sample Home Page (Hello)</h1> | |
<p> | |
Welcome<c:if test="${!principal.principal.newUser}"> back,</c:if> ${principal.principal.name} | |
</p> | |
<c:if test="${principal.principal.newUser}"> | |
<p> | |
As a first time user of this site, your OpenID identity has been registered | |
by the application and will be recognized if you return. | |
</p> | |
</c:if> | |
<h3>Technical Information</h3> | |
<p> | |
Hello World. Your principal object is....: ${principal} | |
</p> | |
<ul> | |
<li><a href="<c:url value="/"/>">Home</a></li> | |
<li><a href="j_spring_security_logout">Logout</a></li> | |
</ul> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication"> | |
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> | |
<listEntry value="/auth"/> | |
</listAttribute> | |
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> | |
<listEntry value="4"/> | |
</listAttribute> | |
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/> | |
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.hsqldb.Server"/> | |
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="auth"/> | |
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/> | |
</launchConfiguration> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<jsp:forward page="/home" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<jsp:forward page="/home" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* jQuery JavaScript Library v1.4.2 | |
* http://jquery.com/ | |
* | |
* Copyright 2010, John Resig | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
* | |
* Includes Sizzle.js | |
* http://sizzlejs.com/ | |
* Copyright 2010, The Dojo Foundation | |
* Released under the MIT, BSD, and GPL Licenses. | |
* | |
* Date: Sat Feb 13 22:33:48 2010 -0500 | |
*/ | |
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i? | |
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r= | |
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g, | |
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e= | |
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, | |
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& | |
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, | |
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== | |
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, | |
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)|| | |
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded", | |
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype, | |
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+ | |
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f], | |
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]=== | |
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&& | |
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari= | |
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; | |
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, | |
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= | |
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= | |
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, | |
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; | |
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, | |
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== | |
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, | |
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ", | |
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ", | |
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className= | |
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i= | |
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= | |
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); | |
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, | |
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); | |
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), | |
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!= | |
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type= | |
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& | |
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; | |
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), | |
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop|| | |
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this, | |
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent= | |
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y, | |
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit= | |
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}}; | |
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", | |
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, | |
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, | |
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&& | |
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}}, | |
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector, | |
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "), | |
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q]; | |
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, | |
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); | |
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| | |
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[]; | |
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length- | |
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, | |
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}}, | |
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]= | |
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[]; | |
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, | |
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, | |
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, | |
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, | |
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= | |
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m= | |
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== | |
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, | |
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition|| | |
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m= | |
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& | |
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>"; | |
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); | |
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: | |
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/, | |
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length; | |
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= | |
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== | |
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", | |
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? | |
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== | |
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)? | |
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= | |
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, | |
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, | |
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, | |
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); | |
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, | |
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&& | |
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]|| | |
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length=== | |
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); | |
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", | |
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= | |
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? | |
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= | |
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= | |
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, | |
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= | |
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= | |
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== | |
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, | |
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), | |
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, | |
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& | |
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? | |
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== | |
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= | |
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", | |
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| | |
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); | |
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== | |
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== | |
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; | |
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay"); | |
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a], | |
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)}, | |
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing= | |
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]); | |
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== | |
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| | |
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; | |
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= | |
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, | |
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length|| | |
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement? | |
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b= | |
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle; | |
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&& | |
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; | |
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); | |
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, | |
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- | |
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": | |
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in | |
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE | |
("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE | |
OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. | |
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS | |
OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE | |
OF SUCH TERMS AND CONDITIONS. | |
1. Definitions | |
a. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, | |
in which the Work in its entirety in unmodified form, along with a number of other | |
contributions, constituting separate and independent works in themselves, are assembled | |
into a collective whole. A work that constitutes a Collective Work will not be | |
considered a Derivative Work (as defined below) for the purposes of this License. | |
b. "Derivative Work" means a work based upon the Work or upon the Work and other | |
pre-existing works, such as a translation, musical arrangement, dramatization, | |
fictionalization, motion picture version, sound recording, art reproduction, abridgment, | |
condensation, or any other form in which the Work may be recast, transformed, or adapted, | |
except that a work that constitutes a Collective Work will not be considered a Derivative | |
Work for the purpose of this License. For the avoidance of doubt, where the Work is a | |
musical composition or sound recording, the synchronization of the Work in timed-relation | |
with a moving image ("synching") will be considered a Derivative Work for the purpose of | |
this License. | |
c. "Licensor" means the individual or entity that offers the Work under the terms of this | |
License. | |
d. "Original Author" means the individual or entity who created the Work. | |
e. "Work" means the copyrightable work of authorship offered under the terms of this | |
License. | |
f. "You" means an individual or entity exercising rights under this License who has not | |
previously violated the terms of this License with respect to the Work, or who has | |
received express permission from the Licensor to exercise rights under this License | |
despite a previous violation. | |
g. "License Elements" means the following high-level license attributes as selected by | |
Licensor and indicated in the title of this License: Attribution, ShareAlike. | |
2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights | |
arising from fair use, first sale or other limitations on the exclusive rights of the copyright | |
owner under copyright law or other applicable laws. | |
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants | |
You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable | |
copyright) license to exercise the rights in the Work as stated below: | |
a. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to | |
reproduce the Work as incorporated in the Collective Works; | |
b. to create and reproduce Derivative Works; | |
c. to distribute copies or phonorecords of, display publicly, perform publicly, and perform | |
publicly by means of a digital audio transmission the Work including as incorporated in | |
Collective Works; | |
d. to distribute copies or phonorecords of, display publicly, perform publicly, and perform | |
publicly by means of a digital audio transmission Derivative Works. | |
e. For the avoidance of doubt, where the work is a musical composition: | |
i. Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to | |
collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, | |
SESAC), royalties for the public performance or public digital performance (e.g. | |
webcast) of the Work. | |
ii. Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to | |
collect, whether individually or via a music rights society or designated agent (e.g. | |
Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover | |
version") and distribute, subject to the compulsory license created by 17 USC Section | |
115 of the US Copyright Act (or the equivalent in other jurisdictions). | |
f. Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is | |
a sound recording, Licensor waives the exclusive right to collect, whether individually | |
or via a performance-rights society (e.g. SoundExchange), royalties for the public | |
digital performance (e.g. webcast) of the Work, subject to the compulsory license created | |
by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions). | |
The above rights may be exercised in all media and formats whether now known or hereafter devised. | |
The above rights include the right to make such modifications as are technically necessary to | |
exercise the rights in other media and formats. All rights not expressly granted by Licensor are | |
hereby reserved. | |
4. Restrictions.The license granted in Section 3 above is expressly made subject to and limited by | |
the following restrictions: | |
a. You may distribute, publicly display, publicly perform, or publicly digitally perform the | |
Work only under the terms of this License, and You must include a copy of, or the Uniform | |
Resource Identifier for, this License with every copy or phonorecord of the Work You | |
distribute, publicly display, publicly perform, or publicly digitally perform. You may | |
not offer or impose any terms on the Work that alter or restrict the terms of this | |
License or the recipients' exercise of the rights granted hereunder. You may not | |
sublicense the Work. You must keep intact all notices that refer to this License and to | |
the disclaimer of warranties. You may not distribute, publicly display, publicly perform, | |
or publicly digitally perform the Work with any technological measures that control | |
access or use of the Work in a manner inconsistent with the terms of this License | |
Agreement. The above applies to the Work as incorporated in a Collective Work, but this | |
does not require the Collective Work apart from the Work itself to be made subject to the | |
terms of this License. If You create a Collective Work, upon notice from any Licensor You | |
must, to the extent practicable, remove from the Collective Work any reference to such | |
Licensor or the Original Author, as requested. If You create a Derivative Work, upon | |
notice from any Licensor You must, to the extent practicable, remove from the Derivative | |
Work any reference to such Licensor or the Original Author, as requested. | |
b. You may distribute, publicly display, publicly perform, or publicly digitally perform a | |
Derivative Work only under the terms of this License, a later version of this License | |
with the same License Elements as this License, or a Creative Commons iCommons license | |
that contains the same License Elements as this License (e.g. Attribution-ShareAlike 2.0 | |
Japan). You must include a copy of, or the Uniform Resource Identifier for, this License | |
or other license specified in the previous sentence with every copy or phonorecord of | |
each Derivative Work You distribute, publicly display, publicly perform, or publicly | |
digitally perform. You may not offer or impose any terms on the Derivative Works that | |
alter or restrict the terms of this License or the recipients' exercise of the rights | |
granted hereunder, and You must keep intact all notices that refer to this License and to | |
the disclaimer of warranties. You may not distribute, publicly display, publicly perform, | |
or publicly digitally perform the Derivative Work with any technological measures that | |
control access or use of the Work in a manner inconsistent with the terms of this License | |
Agreement. The above applies to the Derivative Work as incorporated in a Collective Work, | |
but this does not require the Collective Work apart from the Derivative Work itself to be | |
made subject to the terms of this License. | |
c. If you distribute, publicly display, publicly perform, or publicly digitally perform the | |
Work or any Derivative Works or Collective Works, You must keep intact all copyright | |
notices for the Work and give the Original Author credit reasonable to the medium or | |
means You are utilizing by conveying the name (or pseudonym if applicable) of the | |
Original Author if supplied; the title of the Work if supplied; to the extent reasonably | |
practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be | |
associated with the Work, unless such URI does not refer to the copyright notice or | |
licensing information for the Work; and in the case of a Derivative Work, a credit | |
identifying the use of the Work in the Derivative Work (e.g., "French translation of the | |
Work by Original Author," or "Screenplay based on original Work by Original Author"). | |
Such credit may be implemented in any reasonable manner; provided, however, that in the | |
case of a Derivative Work or Collective Work, at a minimum such credit will appear where | |
any other comparable authorship credit appears and in a manner at least as prominent as | |
such other comparable authorship credit. | |
5. Representations, Warranties and Disclaimer | |
UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO | |
REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR | |
OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A | |
PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE | |
PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE | |
EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. | |
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL | |
LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE | |
OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN | |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
7. Termination | |
a. This License and the rights granted hereunder will terminate automatically upon any | |
breach by You of the terms of this License. Individuals or entities who have received | |
Derivative Works or Collective Works from You under this License, however, will not have | |
their licenses terminated provided such individuals or entities remain in full compliance | |
with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this | |
License. | |
b. Subject to the above terms and conditions, the license granted here is perpetual (for the | |
duration of the applicable copyright in the Work). Notwithstanding the above, Licensor | |
reserves the right to release the Work under different license terms or to stop | |
distributing the Work at any time; provided, however that any such election will not | |
serve to withdraw this License (or any other license that has been, or is required to be, | |
granted under the terms of this License), and this License will continue in full force | |
and effect unless terminated as stated above. | |
8. Miscellaneous | |
a. Each time You distribute or publicly digitally perform the Work or a Collective Work, the | |
Licensor offers to the recipient a license to the Work on the same terms and conditions | |
as the license granted to You under this License. | |
b. Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers | |
to the recipient a license to the original Work on the same terms and conditions as the | |
license granted to You under this License. | |
c. If any provision of this License is invalid or unenforceable under applicable law, it | |
shall not affect the validity or enforceability of the remainder of the terms of this | |
License, and without further action by the parties to this agreement, such provision | |
shall be reformed to the minimum extent necessary to make such provision valid and | |
enforceable. | |
d. No term or provision of this License shall be deemed waived and no breach consented to | |
unless such waiver or consent shall be in writing and signed by the party to be charged | |
with such waiver or consent. | |
e. This License constitutes the entire agreement between the parties with respect to the | |
Work licensed here. There are no understandings, agreements or representations with | |
respect to the Work not specified here. Licensor shall not be bound by any additional | |
provisions that may appear in any communication from You. This License may not be | |
modified without the mutual written agreement of the Licensor and You. | |
Creative Commons is not a party to this License, and makes no warranty whatsoever in connection | |
with the Work. Creative Commons will not be liable to You or any party on any legal theory for | |
any damages whatsoever, including without limitation any general, special, incidental or | |
consequential damages arising in connection to this license. Notwithstanding the foregoing two | |
(2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, | |
it shall have all rights and obligations of Licensor. | |
Except for the limited purpose of indicating to the public that the Work is licensed under the | |
CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo | |
of Creative Commons without the prior written consent of Creative Commons. Any permitted use will | |
be in compliance with Creative Commons' then-current trademark usage guidelines, as may be | |
published on its website or otherwise made available upon request from time to time. | |
Creative Commons may be contacted at http://creativecommons.org/. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE | |
("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE | |
OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. | |
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS | |
OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE | |
OF SUCH TERMS AND CONDITIONS. | |
1. Definitions | |
a. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, | |
in which the Work in its entirety in unmodified form, along with a number of other | |
contributions, constituting separate and independent works in themselves, are assembled | |
into a collective whole. A work that constitutes a Collective Work will not be | |
considered a Derivative Work (as defined below) for the purposes of this License. | |
b. "Derivative Work" means a work based upon the Work or upon the Work and other | |
pre-existing works, such as a translation, musical arrangement, dramatization, | |
fictionalization, motion picture version, sound recording, art reproduction, abridgment, | |
condensation, or any other form in which the Work may be recast, transformed, or adapted, | |
except that a work that constitutes a Collective Work will not be considered a Derivative | |
Work for the purpose of this License. For the avoidance of doubt, where the Work is a | |
musical composition or sound recording, the synchronization of the Work in timed-relation | |
with a moving image ("synching") will be considered a Derivative Work for the purpose of | |
this License. | |
c. "Licensor" means the individual or entity that offers the Work under the terms of this | |
License. | |
d. "Original Author" means the individual or entity who created the Work. | |
e. "Work" means the copyrightable work of authorship offered under the terms of this | |
License. | |
f. "You" means an individual or entity exercising rights under this License who has not | |
previously violated the terms of this License with respect to the Work, or who has | |
received express permission from the Licensor to exercise rights under this License | |
despite a previous violation. | |
g. "License Elements" means the following high-level license attributes as selected by | |
Licensor and indicated in the title of this License: Attribution, ShareAlike. | |
2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights | |
arising from fair use, first sale or other limitations on the exclusive rights of the copyright | |
owner under copyright law or other applicable laws. | |
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants | |
You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable | |
copyright) license to exercise the rights in the Work as stated below: | |
a. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to | |
reproduce the Work as incorporated in the Collective Works; | |
b. to create and reproduce Derivative Works; | |
c. to distribute copies or phonorecords of, display publicly, perform publicly, and perform | |
publicly by means of a digital audio transmission the Work including as incorporated in | |
Collective Works; | |
d. to distribute copies or phonorecords of, display publicly, perform publicly, and perform | |
publicly by means of a digital audio transmission Derivative Works. | |
e. For the avoidance of doubt, where the work is a musical composition: | |
i. Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to | |
collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, | |
SESAC), royalties for the public performance or public digital performance (e.g. | |
webcast) of the Work. | |
ii. Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to | |
collect, whether individually or via a music rights society or designated agent (e.g. | |
Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover | |
version") and distribute, subject to the compulsory license created by 17 USC Section | |
115 of the US Copyright Act (or the equivalent in other jurisdictions). | |
f. Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is | |
a sound recording, Licensor waives the exclusive right to collect, whether individually | |
or via a performance-rights society (e.g. SoundExchange), royalties for the public | |
digital performance (e.g. webcast) of the Work, subject to the compulsory license created | |
by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions). | |
The above rights may be exercised in all media and formats whether now known or hereafter devised. | |
The above rights include the right to make such modifications as are technically necessary to | |
exercise the rights in other media and formats. All rights not expressly granted by Licensor are | |
hereby reserved. | |
4. Restrictions.The license granted in Section 3 above is expressly made subject to and limited by | |
the following restrictions: | |
a. You may distribute, publicly display, publicly perform, or publicly digitally perform the | |
Work only under the terms of this License, and You must include a copy of, or the Uniform | |
Resource Identifier for, this License with every copy or phonorecord of the Work You | |
distribute, publicly display, publicly perform, or publicly digitally perform. You may | |
not offer or impose any terms on the Work that alter or restrict the terms of this | |
License or the recipients' exercise of the rights granted hereunder. You may not | |
sublicense the Work. You must keep intact all notices that refer to this License and to | |
the disclaimer of warranties. You may not distribute, publicly display, publicly perform, | |
or publicly digitally perform the Work with any technological measures that control | |
access or use of the Work in a manner inconsistent with the terms of this License | |
Agreement. The above applies to the Work as incorporated in a Collective Work, but this | |
does not require the Collective Work apart from the Work itself to be made subject to the | |
terms of this License. If You create a Collective Work, upon notice from any Licensor You | |
must, to the extent practicable, remove from the Collective Work any reference to such | |
Licensor or the Original Author, as requested. If You create a Derivative Work, upon | |
notice from any Licensor You must, to the extent practicable, remove from the Derivative | |
Work any reference to such Licensor or the Original Author, as requested. | |
b. You may distribute, publicly display, publicly perform, or publicly digitally perform a | |
Derivative Work only under the terms of this License, a later version of this License | |
with the same License Elements as this License, or a Creative Commons iCommons license | |
that contains the same License Elements as this License (e.g. Attribution-ShareAlike 2.0 | |
Japan). You must include a copy of, or the Uniform Resource Identifier for, this License | |
or other license specified in the previous sentence with every copy or phonorecord of | |
each Derivative Work You distribute, publicly display, publicly perform, or publicly | |
digitally perform. You may not offer or impose any terms on the Derivative Works that | |
alter or restrict the terms of this License or the recipients' exercise of the rights | |
granted hereunder, and You must keep intact all notices that refer to this License and to | |
the disclaimer of warranties. You may not distribute, publicly display, publicly perform, | |
or publicly digitally perform the Derivative Work with any technological measures that | |
control access or use of the Work in a manner inconsistent with the terms of this License | |
Agreement. The above applies to the Derivative Work as incorporated in a Collective Work, | |
but this does not require the Collective Work apart from the Derivative Work itself to be | |
made subject to the terms of this License. | |
c. If you distribute, publicly display, publicly perform, or publicly digitally perform the | |
Work or any Derivative Works or Collective Works, You must keep intact all copyright | |
notices for the Work and give the Original Author credit reasonable to the medium or | |
means You are utilizing by conveying the name (or pseudonym if applicable) of the | |
Original Author if supplied; the title of the Work if supplied; to the extent reasonably | |
practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be | |
associated with the Work, unless such URI does not refer to the copyright notice or | |
licensing information for the Work; and in the case of a Derivative Work, a credit | |
identifying the use of the Work in the Derivative Work (e.g., "French translation of the | |
Work by Original Author," or "Screenplay based on original Work by Original Author"). | |
Such credit may be implemented in any reasonable manner; provided, however, that in the | |
case of a Derivative Work or Collective Work, at a minimum such credit will appear where | |
any other comparable authorship credit appears and in a manner at least as prominent as | |
such other comparable authorship credit. | |
5. Representations, Warranties and Disclaimer | |
UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO | |
REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR | |
OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A | |
PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE | |
PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE | |
EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. | |
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL | |
LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE | |
OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN | |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
7. Termination | |
a. This License and the rights granted hereunder will terminate automatically upon any | |
breach by You of the terms of this License. Individuals or entities who have received | |
Derivative Works or Collective Works from You under this License, however, will not have | |
their licenses terminated provided such individuals or entities remain in full compliance | |
with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this | |
License. | |
b. Subject to the above terms and conditions, the license granted here is perpetual (for the | |
duration of the applicable copyright in the Work). Notwithstanding the above, Licensor | |
reserves the right to release the Work under different license terms or to stop | |
distributing the Work at any time; provided, however that any such election will not | |
serve to withdraw this License (or any other license that has been, or is required to be, | |
granted under the terms of this License), and this License will continue in full force | |
and effect unless terminated as stated above. | |
8. Miscellaneous | |
a. Each time You distribute or publicly digitally perform the Work or a Collective Work, the | |
Licensor offers to the recipient a license to the Work on the same terms and conditions | |
as the license granted to You under this License. | |
b. Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers | |
to the recipient a license to the original Work on the same terms and conditions as the | |
license granted to You under this License. | |
c. If any provision of this License is invalid or unenforceable under applicable law, it | |
shall not affect the validity or enforceability of the remainder of the terms of this | |
License, and without further action by the parties to this agreement, such provision | |
shall be reformed to the minimum extent necessary to make such provision valid and | |
enforceable. | |
d. No term or provision of this License shall be deemed waived and no breach consented to | |
unless such waiver or consent shall be in writing and signed by the party to be charged | |
with such waiver or consent. | |
e. This License constitutes the entire agreement between the parties with respect to the | |
Work licensed here. There are no understandings, agreements or representations with | |
respect to the Work not specified here. Licensor shall not be bound by any additional | |
provisions that may appear in any communication from You. This License may not be | |
modified without the mutual written agreement of the Licensor and You. | |
Creative Commons is not a party to this License, and makes no warranty whatsoever in connection | |
with the Work. Creative Commons will not be liable to You or any party on any legal theory for | |
any damages whatsoever, including without limitation any general, special, incidental or | |
consequential damages arising in connection to this license. Notwithstanding the foregoing two | |
(2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, | |
it shall have all rights and obligations of Licensor. | |
Except for the limited purpose of indicating to the public that the Work is licensed under the | |
CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo | |
of Creative Commons without the prior written consent of Creative Commons. Any permitted use will | |
be in compliance with Creative Commons' then-current trademark usage guidelines, as may be | |
published on its website or otherwise made available upon request from time to time. | |
Creative Commons may be contacted at http://creativecommons.org/. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
log4j.rootCategory=INFO, CONSOLE | |
# CONSOLE is set to be a ConsoleAppender using a PatternLayout. | |
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender | |
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout | |
log4j.appender.CONSOLE.layout.ConversionPattern=%d %p [%c] (%x:%t) - <%m>%n | |
#log4j.category.org.springframework.security=DEBUG | |
#log4j.category.org.springframework.web=DEBUG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
log4j.rootCategory=INFO, CONSOLE | |
# CONSOLE is set to be a ConsoleAppender using a PatternLayout. | |
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender | |
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout | |
log4j.appender.CONSOLE.layout.ConversionPattern=%d %p [%c] (%x:%t) - <%m>%n | |
log4j.category.org.springframework.security=DEBUG | |
log4j.category.org.openid4java=DEBUG | |
log4j.category.org.cloudfoundry.identity=DEBUG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
log4j.rootCategory=INFO, CONSOLE | |
# CONSOLE is set to be a ConsoleAppender using a PatternLayout. | |
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender | |
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout | |
log4j.appender.CONSOLE.layout.ConversionPattern=%d %p [%c] (%x:%t) - <%m>%n | |
log4j.category.org.springframework.security=DEBUG | |
log4j.category.org.cloudfoundry.identity=DEBUG | |
log4j.category.org.openid4java=DEBUG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
log4j.rootCategory=INFO, CONSOLE | |
# CONSOLE is set to be a ConsoleAppender using a PatternLayout. | |
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender | |
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout | |
log4j.appender.CONSOLE.layout.ConversionPattern=%d %p [%c] (%x:%t) - <%m>%n | |
log4j.category.org.springframework.security=DEBUG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
<body> | |
<h1>OpenID Sample Home Page</h1> | |
<p> | |
You are logged out. | |
</p> | |
<ul> | |
<li><a href="photos">Photos</a></li> | |
<li><a href="<c:url value="/"/>">Home</a></li> | |
</ul> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
<body> | |
<h1>OpenID Sample Home Page</h1> | |
<p> | |
You are logged out. | |
</p> | |
<ul> | |
<li><a href="<c:url value="/"/>">Home</a></li> | |
</ul> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ page | |
import="org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter"%> | |
<%@ taglib prefix="authz" | |
uri="http://www.springframework.org/security/tags"%> | |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | |
<title>Authorization Server Login</title> | |
<link type="text/css" rel="stylesheet" | |
href="<c:url value="/resources/style.css"/>" /> | |
</head> | |
<body> | |
<h1>Authentication</h1> | |
<div id="content"> | |
<% | |
if (session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY) != null) { | |
%> | |
<div class="error"> | |
<h2>Woops!</h2> | |
<p> | |
Your login attempt was not successful. (<%=((Exception) session | |
.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)) | |
.getMessage()%>) | |
</p> | |
</div> | |
<% | |
} | |
%> | |
<c:remove scope="session" var="SPRING_SECURITY_LAST_EXCEPTION" /> | |
<authz:authorize ifNotGranted="ROLE_USER"> | |
<h2>Login</h2> | |
<p> | |
You need to authenticate. | |
</p> | |
<p>Enter your user name and password.</p> | |
<form id="loginForm" name="loginForm" | |
action="<c:url value="/login.do"/>" method="POST"> | |
<p> | |
<label>Username: <input type='text' name='username' | |
value="${username}" /> </label> | |
</p> | |
<p> | |
<label>Password: <input type='password' name='password' | |
value="" /> </label> | |
</p> | |
<p> | |
<input name="login" value="Login" type="submit" /> | |
</p> | |
</form> | |
</authz:authorize> | |
</div> | |
<div id="footer">Demo only</div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ page | |
import="org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter"%> | |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
<body> | |
<h1>OpenID Sample Error Page</h1> | |
<p> | |
There was a problem logging you in. Don't panic. | |
</p> | |
<ul> | |
<li><a href="photos">Photos</a></li> | |
<li><a href="<c:url value="/"/>">Home</a></li> | |
</ul> | |
<% | |
if (session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY) != null) { | |
%> | |
<div class="error"> | |
<p> | |
<%= session | |
.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY) %> | |
<% ((Exception) session | |
.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)).printStackTrace();%> | |
</p> | |
</div> | |
<% | |
} | |
%> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ page | |
import="org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter"%> | |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
<body> | |
<h1>OpenID Sample Error Page</h1> | |
<p> | |
There was a problem logging you in. Don't panic. | |
</p> | |
<ul> | |
<li><a href="<c:url value="/"/>">Home</a></li> | |
</ul> | |
<% | |
if (session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY) != null) { | |
%> | |
<div class="error"> | |
<p> | |
<%= session | |
.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY) %> | |
<% ((Exception) session | |
.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)).printStackTrace();%> | |
</p> | |
</div> | |
<% | |
} | |
%> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import java.security.Principal; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.ui.Model; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
@Controller | |
public class LoginController { | |
private String openidProviderUrl; | |
public void setOpenidProviderUrl(String openidProviderUrl) { | |
this.openidProviderUrl = openidProviderUrl; | |
} | |
public String getLoginUrl() { | |
return "/login?action=verify&openid_identifier="+openidProviderUrl; | |
} | |
@RequestMapping("/home") | |
public String home(Model model, Principal principal) { | |
model.addAttribute("principal", principal); | |
return "home"; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import java.security.Principal; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.ui.Model; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
@Controller | |
public class LoginController { | |
private String openidProviderUrl; | |
public void setOpenidProviderUrl(String openidProviderUrl) { | |
this.openidProviderUrl = openidProviderUrl; | |
} | |
public String getLoginUrl() { | |
return "/login?action=verify&openid_identifier="+openidProviderUrl; | |
} | |
@RequestMapping("/home") | |
public String home(Model model, Principal principal) { | |
model.addAttribute("principal", principal); | |
return "home"; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2009-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import java.util.Map; | |
import org.springframework.context.expression.MapAccessor; | |
import org.springframework.expression.spel.standard.SpelExpressionParser; | |
import org.springframework.expression.spel.support.StandardEvaluationContext; | |
public class MapWrapper { | |
private final SpelExpressionParser parser; | |
private final StandardEvaluationContext context; | |
private Object target; | |
public MapWrapper(Object target) throws Exception { | |
this.target = target; | |
context = new StandardEvaluationContext(); | |
context.addPropertyAccessor(new MapAccessor()); | |
parser = new SpelExpressionParser(); | |
} | |
@SuppressWarnings("unchecked") | |
public Map<String, Object> getMap() { | |
return (Map<String, Object>) target; | |
} | |
public Object get(String expression) throws Exception { | |
return get(expression, Object.class); | |
} | |
public <T> T get(String expression, Class<T> type) throws Exception { | |
return parser.parseExpression(expression).getValue(context, target, | |
type); | |
} | |
@Override | |
public String toString() { | |
return target.toString(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2002-2011 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.uaa.web; | |
import java.security.Principal; | |
import java.util.HashMap; | |
import java.util.Map; | |
import javax.servlet.ServletException; | |
import javax.servlet.http.HttpServletRequest; | |
import org.cloudfoundry.identity.uaa.web.OpenIdProviderController.Openid; | |
import org.openid4java.association.AssociationException; | |
import org.openid4java.message.AuthRequest; | |
import org.openid4java.message.AuthSuccess; | |
import org.openid4java.message.Message; | |
import org.openid4java.message.MessageException; | |
import org.openid4java.message.MessageExtension; | |
import org.openid4java.message.Parameter; | |
import org.openid4java.message.ParameterList; | |
import org.openid4java.message.ax.AxMessage; | |
import org.openid4java.message.ax.FetchRequest; | |
import org.openid4java.message.ax.FetchResponse; | |
import org.openid4java.server.ServerException; | |
import org.openid4java.server.ServerManager; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.security.access.AccessDeniedException; | |
import org.springframework.security.authentication.BadCredentialsException; | |
import org.springframework.security.authentication.InsufficientAuthenticationException; | |
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.ui.Model; | |
import org.springframework.util.MultiValueMap; | |
import org.springframework.web.bind.MissingServletRequestParameterException; | |
import org.springframework.web.bind.annotation.ModelAttribute; | |
import org.springframework.web.bind.annotation.PathVariable; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.RequestMethod; | |
import org.springframework.web.bind.annotation.RequestParam; | |
import org.springframework.web.bind.annotation.ResponseBody; | |
import org.springframework.web.bind.annotation.SessionAttributes; | |
import org.springframework.web.bind.support.SessionStatus; | |
import org.springframework.web.servlet.View; | |
import org.springframework.web.servlet.view.RedirectView; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
@Controller | |
@SessionAttributes(types = Openid.class) | |
public class OpenIdProviderController { | |
private ServerManager manager; | |
public void setServerManager(ServerManager manager) { | |
this.manager = manager; | |
} | |
@ModelAttribute | |
public Openid getOpenid() { | |
return new Openid(); | |
} | |
@ModelAttribute | |
public ParameterList getParameterList(HttpServletRequest request) { | |
ParameterList list = new ParameterList(request.getParameterMap()); | |
return list; | |
} | |
// TODO: provide user-friendly HTML output as well | |
@RequestMapping("/openid") | |
public ResponseEntity<String> xrdsDiscovery() { | |
MultiValueMap<String, String> headers = new HttpHeaders(); | |
headers.set("Content-Type", "application/xrds+xml"); | |
return new ResponseEntity<String>(String.format(XRDS_TEMPLATE, manager.getOPEndpointUrl()), headers, HttpStatus.OK); | |
} | |
// TODO: provide user-friendly HTML output as well | |
@RequestMapping("/openid/users/{username}") | |
public ResponseEntity<String> xrdsWithUsername(@PathVariable String username) { | |
MultiValueMap<String, String> headers = new HttpHeaders(); | |
headers.set("Content-Type", "application/xrds+xml"); | |
return new ResponseEntity<String>(String.format(XRDS_TEMPLATE, manager.getOPEndpointUrl() + "/users/" | |
+ username), headers, HttpStatus.OK); | |
} | |
@RequestMapping(value = "/openid/provider", params = "openid.mode=associate") | |
@ResponseBody | |
public String associate(@ModelAttribute Openid openid, @ModelAttribute ParameterList parameterList) { | |
openid.getParameterList().addParams(parameterList); | |
parameterList = openid.getParameterList(); | |
return manager.associationResponse(openid.getParameterList()).keyValueFormEncoding(); | |
} | |
@RequestMapping(value = "/openid/provider", params = "openid.mode=check_authentication") | |
@ResponseBody | |
public String checkAuthentication(@ModelAttribute ParameterList parameterList) { | |
Message responseMessage = manager.verify(parameterList); | |
// This is the back channel (so the session is irrelevant). The response | |
// has to be this precise text. | |
return responseMessage.keyValueFormEncoding(); | |
} | |
@RequestMapping(value = "/openid/provider", params = "openid.mode=checkid_setup") | |
public View checkSetup(@ModelAttribute Openid openid, @ModelAttribute ParameterList parameterList) { | |
openid.getParameterList().addParams(parameterList); | |
return check(openid); | |
} | |
@RequestMapping(value = "/openid/provider", params = "openid.mode=checkid_immediate") | |
public View checkImmediate(@ModelAttribute Openid openid, @ModelAttribute ParameterList parameterList) { | |
openid.getParameterList().addParams(parameterList); | |
return check(openid); | |
} | |
// TODO: deal with openid.mode=cancel | |
@RequestMapping(value = "/openid/complete") | |
public View complete(@ModelAttribute Openid openid, @ModelAttribute ParameterList parameterList, | |
SessionStatus status) throws ServletException, MessageException, ServerException, AssociationException { | |
openid.getParameterList().addParams(parameterList); | |
parameterList = openid.getParameterList(); | |
String mode = openid.getMode(); | |
if (mode != null && mode.startsWith("checkid_")) { | |
// Remove the parameter list so this provider can accept requests | |
// from elsewhere | |
status.setComplete(); | |
boolean authenticatedAndApproved = openid.isApproved(); | |
String userSelectedClaimedId = openid.getClaimedIdentity(); | |
String userSelectedId = openid.getIdentity(); | |
// TODO: something sensible if the user chose a different claimed_id | |
// than the one in request | |
Message response = manager.authResponse(parameterList, userSelectedId, userSelectedClaimedId, | |
authenticatedAndApproved, false); | |
// Sign after we added extensions. | |
if (response instanceof AuthSuccess) { | |
Map<String, String> attributes = openid.getAttributes(); | |
if (!attributes.isEmpty()) { | |
// --- process extensions | |
AuthRequest authReq = AuthRequest.createAuthRequest(parameterList, manager.getRealmVerifier()); | |
if (authReq.hasExtension(AxMessage.OPENID_NS_AX)) { | |
MessageExtension ext = authReq.getExtension(AxMessage.OPENID_NS_AX); | |
if (ext instanceof FetchRequest) { | |
FetchRequest fetchReq = (FetchRequest) ext; | |
Map<String, String> userDataExt = new HashMap<String, String>(); | |
FetchResponse fetchResp = FetchResponse.createFetchResponse(fetchReq, userDataExt); | |
@SuppressWarnings("unchecked") | |
Map<String, String> required = fetchReq.getAttributes(true); | |
for (String key : required.keySet()) { | |
if (attributes.containsKey(key)) { | |
fetchResp.addAttribute(key, required.get(key), attributes.get(key)); | |
} | |
else { | |
throw new BadCredentialsException("Required OpenID attribute (" + key | |
+ ") not found."); | |
} | |
} | |
@SuppressWarnings("unchecked") | |
Map<String, String> optional = fetchReq.getAttributes(false); | |
for (String key : optional.keySet()) { | |
if (attributes.containsKey(key)) { | |
fetchResp.addAttribute(key, optional.get(key), attributes.get(key)); | |
} | |
} | |
response.addExtension(fetchResp); | |
} | |
else { // if (ext instanceof StoreRequest) | |
throw new UnsupportedOperationException("Only fetch request is supported"); | |
} | |
} | |
} | |
// Sign the auth success message. | |
manager.sign((AuthSuccess) response); | |
// GET HTTP-redirect to the return_to URL | |
return new RedirectView(response.getDestinationUrl(true), false); | |
} | |
// TODO: this is what happens with openid.mode=cancel | |
throw new AccessDeniedException("OpenID authentication failed (" + response.wwwFormEncoding() + ")"); | |
} | |
throw new MissingServletRequestParameterException("openid.mode", "string"); | |
} | |
private View check(Openid openid) { | |
boolean authenticatedAndApproved = openid.isApproved(); | |
if (!authenticatedAndApproved) { | |
return new RedirectView("/openid/authorize", true); | |
} | |
// TODO: don't do this, it's dumb. | |
throw new InsufficientAuthenticationException("Not yet approved"); | |
} | |
@RequestMapping(value = "/openid/authorize", method = RequestMethod.GET) | |
public String authorize(@ModelAttribute Openid openid, Model model, Principal user) { | |
model.addAttribute("openid", openid); | |
model.addAttribute("user", user); | |
return "openid_authorize"; | |
} | |
@RequestMapping(value = "/openid/authorize", method = RequestMethod.POST) | |
public View authorize(@ModelAttribute Openid openid, Principal user, | |
@RequestParam(required = false) String approve, @RequestParam(required = false) String deny) { | |
// TODO: if approved is false you get openid.mode=cancel | |
openid.setApproved(approve != null && deny == null); | |
String name = user.getName(); | |
if (name != null && name.contains("@")) { | |
name = name.substring(0, name.indexOf("@")); | |
name = name.replace(".", " "); | |
} | |
String email = user.getName(); | |
if (email != null && !email.contains("@")) { | |
email = email + "@test.org"; | |
} | |
if (user instanceof UsernamePasswordAuthenticationToken) { | |
if (((UsernamePasswordAuthenticationToken) user).getDetails() instanceof Map) { | |
@SuppressWarnings("unchecked") | |
Map<String, String> details = (Map<String, String>) ((UsernamePasswordAuthenticationToken) user) | |
.getDetails(); | |
openid.getAttributes().putAll(details); | |
} | |
} | |
openid.getAttributes().put("email", email); | |
openid.getAttributes().put("fullname", name); | |
openid.setClaimedIdentity(openid.getIdentity() + "/users/" + name); | |
return new RedirectView("/openid/complete", true); | |
} | |
private static String XRDS_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" // | |
+ "<xrds:XRDS xmlns:xrds=\"xri://$xrds\" xmlns:openid=\"http://openid.net/xmlns/1.0\" xmlns=\"xri://$xrd*($v*2.0)\">" // | |
+ "<XRD><Service priority=\"0\">" // | |
+ "<Type>http://openid.net/signon/1.0</Type>" // | |
+ "<URI>%s</URI>" // | |
+ "</Service></XRD>" // | |
+ "</xrds:XRDS>";; | |
public static class Openid { | |
private boolean approved = false; | |
private Map<String, String> attributes = new HashMap<String, String>(); | |
private ParameterList list = new ParameterList(); | |
public ParameterList getParameterList() { | |
Map<String, String> map = new HashMap<String, String>(); | |
list.addParams(new ParameterList(map)); | |
return list; | |
} | |
public Map<String, String> getAttributes() { | |
return attributes; | |
} | |
public String getSite() { | |
return list.getParameterValue("openid.return_to") != null ? list.getParameterValue("openid.return_to") | |
: list.getParameterValue("openid.realm"); | |
} | |
public String getMode() { | |
return list.getParameterValue("openid.mode"); | |
} | |
public String getClaimedIdentity() { | |
return list.getParameterValue("openid.claimed_id"); | |
} | |
public void setClaimedIdentity(String value) { | |
list.set(new Parameter("openid.claimed_id", value)); | |
} | |
public String getIdentity() { | |
return list.getParameterValue("openid.identity"); | |
} | |
public boolean isApproved() { | |
return approved; | |
} | |
public void setApproved(boolean approved) { | |
this.approved = approved; | |
} | |
@Override | |
public String toString() { | |
return list.toString(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.api.web.mvc; | |
import java.io.ByteArrayOutputStream; | |
import java.io.InputStream; | |
import java.util.Collection; | |
import java.util.Map; | |
import org.cloudfoundry.identity.api.PhotoInfo; | |
import org.cloudfoundry.identity.api.PhotoService; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.web.bind.annotation.PathVariable; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
/** | |
* Controller for a specific photo. | |
* | |
* @author Ryan Heaton | |
* @author Dave Syer | |
*/ | |
@Controller | |
public class PhotoController { | |
private PhotoService photoService; | |
@RequestMapping("/photos/{id}") | |
public ResponseEntity<byte[]> getPhoto(@PathVariable("id") String id) throws Exception { | |
InputStream photo = photoService.loadPhoto(id); | |
if (photo == null) { | |
return new ResponseEntity<byte[]>(HttpStatus.NOT_FOUND); | |
} else { | |
ByteArrayOutputStream out = new ByteArrayOutputStream(1024); | |
byte[] buffer = new byte[1024]; | |
int len = photo.read(buffer); | |
while (len >= 0) { | |
out.write(buffer, 0, len); | |
len = photo.read(buffer); | |
} | |
HttpHeaders headers = new HttpHeaders(); | |
headers.setContentType(MediaType.IMAGE_JPEG); | |
return new ResponseEntity<byte[]>(out.toByteArray(), headers, HttpStatus.OK); | |
} | |
} | |
@RequestMapping("/photos") | |
public String list(Map<String,Collection<PhotoInfo>> model) { | |
model.put("photos", photoService.getPhotosForCurrentUser()); | |
return "photos"; | |
} | |
public void setPhotoService(PhotoService photoService) { | |
this.photoService = photoService; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.Map; | |
import org.springframework.http.HttpEntity; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpMethod; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.ui.Model; | |
import org.springframework.web.bind.annotation.PathVariable; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.ResponseBody; | |
import org.springframework.web.client.RestOperations; | |
@Controller | |
public class PhotoController { | |
private RestOperations restTemplate; | |
private String photoListUrl; | |
private String photoUrlPattern; | |
private String photoUrlPassthruPattern; | |
public void setPhotoUrlPassthruPattern(String photoUrlPassthruPattern) { | |
this.photoUrlPassthruPattern = photoUrlPassthruPattern; | |
} | |
public void setPhotoListUrl(String photoListUrl) { | |
this.photoListUrl = photoListUrl; | |
} | |
public void setPhotoUrlPattern(String photoUrlPattern) { | |
this.photoUrlPattern = photoUrlPattern; | |
} | |
public void setRestTemplate(RestOperations restTemplate) { | |
this.restTemplate = restTemplate; | |
} | |
@RequestMapping("/photos") | |
public String photos(Model model) { | |
List<String> photos = new ArrayList<String>(); | |
HttpHeaders headers = new HttpHeaders(); | |
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
HttpEntity<?> request = new HttpEntity<String>("", headers); | |
@SuppressWarnings("unchecked") | |
Map<String, List<Map<String, String>>> result = (Map<String, List<Map<String, String>>>) restTemplate.exchange(photoListUrl, HttpMethod.GET, request , Map.class).getBody(); | |
for (Map<String,String> map : result.get("photos")) { | |
photos.add(String.format(photoUrlPattern, map.get("id"))); | |
} | |
model.addAttribute("photos", photos); | |
return "photos"; | |
} | |
@RequestMapping("/photos/{id}") | |
@ResponseBody | |
public ResponseEntity<byte[]> photo(@PathVariable String id) { | |
HttpHeaders headers = new HttpHeaders(); | |
headers.setAccept(Arrays.asList(MediaType.IMAGE_JPEG)); | |
HttpEntity<?> request = new HttpEntity<String>("", headers); | |
byte[] result = restTemplate.exchange(String.format(photoUrlPassthruPattern, id), HttpMethod.GET, request , byte[].class).getBody(); | |
headers.setContentType(MediaType.IMAGE_JPEG); | |
return new ResponseEntity<byte[]>(result, headers, HttpStatus.OK); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.api; | |
/** | |
* Photo information. | |
* | |
* @author Ryan Heaton | |
*/ | |
public class PhotoInfo { | |
private String id; | |
private String resourceURL; | |
private String name; | |
private String userId; | |
/** | |
* Id of the photo. | |
* | |
* @return Id of the photo. | |
*/ | |
public String getId() { | |
return id; | |
} | |
/** | |
* Id of the photo. | |
* | |
* @param id Id of the photo. | |
*/ | |
public void setId(String id) { | |
this.id = id; | |
} | |
/** | |
* The resource URL. | |
* | |
* @return The resource URL. | |
*/ | |
public String getResourceURL() { | |
return resourceURL; | |
} | |
/** | |
* The resource URL. | |
* | |
* @param resourceURL The resource URL | |
*/ | |
public void setResourceURL(String resourceURL) { | |
this.resourceURL = resourceURL; | |
} | |
/** | |
* Name of the photo. | |
* | |
* @return Name of the photo. | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* Name of the photo. | |
* | |
* @param name Name of the photo. | |
*/ | |
public void setName(String name) { | |
this.name = name; | |
} | |
/** | |
* The id of the user to whom the photo belongs. | |
* | |
* @return The id of the user to whom the photo belongs. | |
*/ | |
public String getUserId() { | |
return userId; | |
} | |
/** | |
* The id of the user to whom the photo belongs. | |
* | |
* @param userId The id of the user to whom the photo belongs. | |
*/ | |
public void setUserId(String userId) { | |
this.userId = userId; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2006-2010 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import java.util.List; | |
import java.util.Map; | |
import org.codehaus.jackson.map.ObjectMapper; | |
import org.junit.Test; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class PhotoInfoTests { | |
private String photos = "{\"photos\":[{\"name\":\"photo1.jpg\",\"id\":\"1\",\"userId\":\"marissa\",\"resourceURL\":\"/org/springframework/security/oauth/examples/api/impl/resources/photo1.jpg\"},{\"name\":\"photo3.jpg\",\"id\":\"3\",\"userId\":\"marissa\",\"resourceURL\":\"/org/springframework/security/oauth/examples/api/impl/resources/photo3.jpg\"},{\"name\":\"photo5.jpg\",\"id\":\"5\",\"userId\":\"marissa\",\"resourceURL\":\"/org/springframework/security/oauth/examples/api/impl/resources/photo5.jpg\"}]}"; | |
@SuppressWarnings("rawtypes") | |
@Test | |
public void testSerialization() throws Exception { | |
ObjectMapper mapper = new ObjectMapper(); | |
@SuppressWarnings("unchecked") | |
Map<String,Object> map = mapper.readValue(photos, Map.class); | |
System.err.println(((Map)((List)map.get("photos")).get(0)).get("id").getClass()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | |
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/style.css"/>"/> | |
</head> | |
<body> | |
<h1>OpenID Sample Photos</h1> | |
Your photos: | |
<ul id="picturelist"> | |
<c:forEach var="photo" items="${photos}"> | |
<li><img src="<c:url value="${photo}"/>"/></li> | |
</c:forEach> | |
</ul> | |
<ul> | |
<li><a href="photos">Photos</a></li> | |
<li><a href="<c:url value="/"/>">Home</a></li> | |
<li><a href="j_spring_security_logout">Logout</a></li> | |
</ul> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.api; | |
import java.util.Collection; | |
import java.io.InputStream; | |
/** | |
* Service for retrieving photos. | |
* | |
* @author Ryan Heaton | |
*/ | |
public interface PhotoService { | |
/** | |
* Load the photos for the current user. | |
* | |
* @return The photos for the current user. | |
*/ | |
Collection<PhotoInfo> getPhotosForCurrentUser(); | |
/** | |
* Load a photo by id. | |
* | |
* @param id The id of the photo. | |
* @return The photo that was read. | |
*/ | |
InputStream loadPhoto(String id); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.api.service; | |
import org.cloudfoundry.identity.api.PhotoInfo; | |
import org.cloudfoundry.identity.api.PhotoService; | |
import org.springframework.security.core.context.SecurityContextHolder; | |
import org.springframework.security.core.Authentication; | |
import org.springframework.security.core.userdetails.UserDetails; | |
import org.springframework.security.authentication.BadCredentialsException; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.net.URL; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.List; | |
/** | |
* Basic implementation for the photo service. | |
* | |
* @author Ryan Heaton | |
*/ | |
public class PhotoServiceImpl implements PhotoService { | |
private List<PhotoInfo> photos; | |
public Collection<PhotoInfo> getPhotosForCurrentUser() { | |
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | |
if (authentication.getPrincipal() instanceof UserDetails) { | |
UserDetails details = (UserDetails) authentication.getPrincipal(); | |
String username = details.getUsername(); | |
ArrayList<PhotoInfo> infos = new ArrayList<PhotoInfo>(); | |
for (PhotoInfo info : getPhotos()) { | |
if (username.equals(info.getUserId())) { | |
infos.add(info); | |
} | |
} | |
return infos; | |
} | |
else { | |
throw new BadCredentialsException("Bad credentials: not a username/password authentication."); | |
} | |
} | |
public InputStream loadPhoto(String id) { | |
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | |
if (authentication.getPrincipal() instanceof UserDetails) { | |
UserDetails details = (UserDetails) authentication.getPrincipal(); | |
String username = details.getUsername(); | |
for (PhotoInfo photoInfo : getPhotos()) { | |
if (id.equals(photoInfo.getId()) && username.equals(photoInfo.getUserId())) { | |
URL resourceURL = getClass().getResource(photoInfo.getResourceURL()); | |
if (resourceURL != null) { | |
try { | |
return resourceURL.openStream(); | |
} | |
catch (IOException e) { | |
//fall through... | |
} | |
} | |
} | |
} | |
} | |
return null; | |
} | |
public List<PhotoInfo> getPhotos() { | |
return photos; | |
} | |
public void setPhotos(List<PhotoInfo> photos) { | |
this.photos = photos; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>org.cloudfoundry.runtime</groupId> | |
<artifactId>parent</artifactId> | |
<version>1.0.0.BUILD-SNAPSHOT</version> | |
<relativePath>..</relativePath> | |
</parent> | |
<artifactId>api</artifactId> | |
<packaging>war</packaging> | |
<name>api</name> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-war-plugin</artifactId> | |
<configuration> | |
<warSourceDirectory>src/main/webapp</warSourceDirectory> | |
<webResources> | |
<resource> | |
<directory>src/main/webapp</directory> | |
<filtering>true</filtering> | |
<includes> | |
<include>**/*.xml</include> | |
</includes> | |
</resource> | |
</webResources> | |
</configuration> | |
</plugin> | |
<plugin> | |
<!-- skip unit test run, tests to be executed during integration-test --> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-surefire-plugin</artifactId> | |
<configuration> | |
<skip>true</skip> | |
</configuration> | |
<executions> | |
<execution> | |
<id>surefire-it</id> | |
<phase>integration-test</phase> | |
<goals> | |
<goal>test</goal> | |
</goals> | |
<configuration> | |
<skip>${skipTests}</skip> | |
</configuration> | |
</execution> | |
</executions> | |
</plugin> | |
<plugin> | |
<groupId>org.mortbay.jetty</groupId> | |
<artifactId>maven-jetty-plugin</artifactId> | |
<configuration> | |
<scanIntervalSeconds>10</scanIntervalSeconds> | |
<stopKey>api</stopKey> | |
<stopPort>9999</stopPort> | |
</configuration> | |
<executions> | |
<execution> | |
<id>start-jetty</id> | |
<phase>pre-integration-test</phase> | |
<goals> | |
<goal>run</goal> | |
</goals> | |
<configuration> | |
<scanIntervalSeconds>0</scanIntervalSeconds> | |
<daemon>true</daemon> | |
</configuration> | |
</execution> | |
<execution> | |
<id>stop-jetty</id> | |
<phase>post-integration-test</phase> | |
<goals> | |
<goal>stop</goal> | |
</goals> | |
</execution> | |
</executions> | |
</plugin> | |
<plugin> | |
<!--skip deploy (this is just a test module) --> | |
<artifactId>maven-deploy-plugin</artifactId> | |
<configuration> | |
<skip>true</skip> | |
</configuration> | |
</plugin> | |
</plugins> | |
</build> | |
<dependencies> | |
<dependency> | |
<groupId>org.springframework.security.oauth</groupId> | |
<artifactId>spring-security-oauth2</artifactId> | |
<version>${spring.security.oauth.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-jdbc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-web</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-webmvc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-tx</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-test</artifactId> | |
<version>${spring.version}</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-taglibs</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-web</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-core</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-config</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.codehaus.jackson</groupId> | |
<artifactId>jackson-mapper-asl</artifactId> | |
<version>1.8.3</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>servlet-api</artifactId> | |
<version>2.3</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>jstl</artifactId> | |
<version>1.2</version> | |
</dependency> | |
<dependency> | |
<groupId>log4j</groupId> | |
<artifactId>log4j</artifactId> | |
<version>1.2.14</version> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.8.2</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>net.sourceforge.htmlunit</groupId> | |
<artifactId>htmlunit</artifactId> | |
<version>2.7</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>commons-dbcp</groupId> | |
<artifactId>commons-dbcp</artifactId> | |
<version>1.4</version> | |
</dependency> | |
<dependency> | |
<groupId>org.hsqldb</groupId> | |
<artifactId>hsqldb-j5</artifactId> | |
<version>2.0.0</version> | |
<scope>runtime</scope> | |
</dependency> | |
</dependencies> | |
<!-- <profiles> <profile> <id>gae</id> <dependencies> <dependency> <groupId>com.google.appengine</groupId> | |
<artifactId>api</dependency> | |
</dependencies> </profile> </profiles> --> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | |
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>org.cloudfoundry.runtime</groupId> | |
<artifactId>parent</artifactId> | |
<version>1.0.0.BUILD-SNAPSHOT</version> | |
<relativePath>..</relativePath> | |
</parent> | |
<artifactId>app</artifactId> | |
<packaging>war</packaging> | |
<name>app</name> | |
<dependencies> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-openid</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>compile</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.mockito</groupId> | |
<artifactId>mockito-core</artifactId> | |
<version>1.8.5</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-core</artifactId> | |
<version>${spring.version}</version> | |
<scope>compile</scope> | |
<exclusions> | |
<exclusion> | |
<artifactId>commons-logging</artifactId> | |
<groupId>commons-logging</groupId> | |
</exclusion> | |
</exclusions> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>jcl-over-slf4j</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>log4j</groupId> | |
<artifactId>log4j</artifactId> | |
<version>1.2.14</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-test</artifactId> | |
<version>${spring.version}</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-beans</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-context</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-aop</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-tx</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-jdbc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-web</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-webmvc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>jstl</artifactId> | |
<version>1.2</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-core</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>compile</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security.oauth</groupId> | |
<artifactId>spring-security-oauth2</artifactId> | |
<version>${spring.security.oauth.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>servlet-api</artifactId> | |
<version>2.5</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.7</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-taglibs</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-config</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.codehaus.jackson</groupId> | |
<artifactId>jackson-mapper-asl</artifactId> | |
<version>1.8.3</version> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-api</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-log4j12</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.httpcomponents</groupId> | |
<artifactId>httpclient</artifactId> | |
<version>4.1.1</version> | |
<scope>runtime</scope> | |
</dependency> | |
</dependencies> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>org.cloudfoundry.runtime</groupId> | |
<artifactId>parent</artifactId> | |
<version>1.0.0.BUILD-SNAPSHOT</version> | |
<relativePath>..</relativePath> | |
</parent> | |
<artifactId>auth</artifactId> | |
<packaging>war</packaging> | |
<name>auth</name> | |
<profiles> | |
<profile> | |
<id>rundb</id> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.codehaus.mojo</groupId> | |
<artifactId>exec-maven-plugin</artifactId> | |
<version>1.1</version> | |
<configuration> | |
<mainClass>org.hsqldb.Server</mainClass> | |
<classpathScope>runtime</classpathScope> | |
</configuration> | |
</plugin> | |
</plugins> | |
</build> | |
</profile> | |
</profiles> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-war-plugin</artifactId> | |
<configuration> | |
<warSourceDirectory>src/main/webapp</warSourceDirectory> | |
<webResources> | |
<resource> | |
<directory>src/main/webapp</directory> | |
<filtering>true</filtering> | |
<includes> | |
<include>**/*.xml</include> | |
</includes> | |
</resource> | |
</webResources> | |
</configuration> | |
</plugin> | |
<plugin> | |
<!-- skip unit test run, tests to be executed during integration-test --> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-surefire-plugin</artifactId> | |
<configuration> | |
<skip>true</skip> | |
</configuration> | |
<executions> | |
<execution> | |
<id>surefire-it</id> | |
<phase>integration-test</phase> | |
<goals> | |
<goal>test</goal> | |
</goals> | |
<configuration> | |
<skip>${skipTests}</skip> | |
</configuration> | |
</execution> | |
</executions> | |
</plugin> | |
<plugin> | |
<groupId>org.mortbay.jetty</groupId> | |
<artifactId>maven-jetty-plugin</artifactId> | |
<configuration> | |
<scanIntervalSeconds>10</scanIntervalSeconds> | |
<stopKey>auth</stopKey> | |
<stopPort>9999</stopPort> | |
</configuration> | |
<executions> | |
<execution> | |
<id>start-jetty</id> | |
<phase>pre-integration-test</phase> | |
<goals> | |
<goal>run</goal> | |
</goals> | |
<configuration> | |
<scanIntervalSeconds>0</scanIntervalSeconds> | |
<daemon>true</daemon> | |
</configuration> | |
</execution> | |
<execution> | |
<id>stop-jetty</id> | |
<phase>post-integration-test</phase> | |
<goals> | |
<goal>stop</goal> | |
</goals> | |
</execution> | |
</executions> | |
</plugin> | |
<plugin> | |
<!--skip deploy (this is just a test module) --> | |
<artifactId>maven-deploy-plugin</artifactId> | |
<configuration> | |
<skip>true</skip> | |
</configuration> | |
</plugin> | |
</plugins> | |
</build> | |
<dependencies> | |
<dependency> | |
<groupId>org.springframework.security.oauth</groupId> | |
<artifactId>spring-security-oauth2</artifactId> | |
<version>${spring.security.oauth.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-web</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-jdbc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-webmvc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-tx</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-test</artifactId> | |
<version>${spring.version}</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-ldap</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-openid</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-web</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-taglibs</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-config</artifactId> | |
<version>${spring.security.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>commons-dbcp</groupId> | |
<artifactId>commons-dbcp</artifactId> | |
<version>1.4</version> | |
</dependency> | |
<dependency> | |
<groupId>log4j</groupId> | |
<artifactId>log4j</artifactId> | |
<version>1.2.14</version> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-api</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-log4j12</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>servlet-api</artifactId> | |
<version>2.5</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>jstl</artifactId> | |
<version>1.2</version> | |
</dependency> | |
<dependency> | |
<groupId>org.codehaus.jackson</groupId> | |
<artifactId>jackson-mapper-asl</artifactId> | |
<version>1.8.3</version> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.8.2</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.hsqldb</groupId> | |
<artifactId>hsqldb-j5</artifactId> | |
<version>2.0.0</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.directory.server</groupId> | |
<artifactId>apacheds-protocol-ldap</artifactId> | |
<version>1.5.5</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.directory.shared</groupId> | |
<artifactId>shared-ldap</artifactId> | |
<version>0.9.15</version> | |
</dependency> | |
</dependencies> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | |
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>org.cloudfoundry.runtime</groupId> | |
<artifactId>parent</artifactId> | |
<version>1.0.0.BUILD-SNAPSHOT</version> | |
<relativePath>..</relativePath> | |
</parent> | |
<artifactId>hello</artifactId> | |
<packaging>war</packaging> | |
<name>hello</name> | |
<dependencies> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-openid</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>compile</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.mockito</groupId> | |
<artifactId>mockito-core</artifactId> | |
<version>1.8.5</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-core</artifactId> | |
<version>${spring.version}</version> | |
<scope>compile</scope> | |
<exclusions> | |
<exclusion> | |
<artifactId>commons-logging</artifactId> | |
<groupId>commons-logging</groupId> | |
</exclusion> | |
</exclusions> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>jcl-over-slf4j</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>log4j</groupId> | |
<artifactId>log4j</artifactId> | |
<version>1.2.14</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-test</artifactId> | |
<version>${spring.version}</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-web</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-beans</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-aop</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-context</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-tx</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-jdbc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-webmvc</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>jstl</artifactId> | |
<version>1.2</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-core</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>compile</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security.oauth</groupId> | |
<artifactId>spring-security-oauth2</artifactId> | |
<version>${spring.security.oauth.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>servlet-api</artifactId> | |
<version>2.5</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.7</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-taglibs</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.security</groupId> | |
<artifactId>spring-security-config</artifactId> | |
<version>${spring.security.version}</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.codehaus.jackson</groupId> | |
<artifactId>jackson-mapper-asl</artifactId> | |
<version>1.8.3</version> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-api</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-log4j12</artifactId> | |
<version>1.5.8</version> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.httpcomponents</groupId> | |
<artifactId>httpclient</artifactId> | |
<version>4.1.1</version> | |
<scope>runtime</scope> | |
</dependency> | |
</dependencies> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>org.cloudfoundry.runtime</groupId> | |
<artifactId>parent</artifactId> | |
<name>parent</name> | |
<packaging>pom</packaging> | |
<version>1.0.0.BUILD-SNAPSHOT</version> | |
<modules> | |
<module>auth</module> | |
<module>api</module> | |
<module>app</module> | |
<module>hello</module> | |
</modules> | |
<properties> | |
<spring.version>3.1.0.RELEASE</spring.version> | |
<spring.security.version>3.1.0.RELEASE</spring.security.version> | |
<spring.security.oauth.version>1.0.0.BUILD-SNAPSHOT</spring.security.oauth.version> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |
</properties> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-compiler-plugin</artifactId> | |
<version>2.3.2</version> | |
<configuration> | |
<source>1.6</source> | |
<target>1.6</target> | |
</configuration> | |
</plugin> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-idea-plugin</artifactId> | |
<version>2.3-atlassian-1</version> | |
<configuration> | |
<downloadSources>true</downloadSources> | |
<downloadJavadocs>true</downloadJavadocs> | |
<exclude>cargo-installs,target/tomcat5x,target/war</exclude> | |
</configuration> | |
</plugin> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-eclipse-plugin</artifactId> | |
<configuration> | |
<additionalProjectnatures> | |
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature> | |
</additionalProjectnatures> | |
<additionalBuildcommands> | |
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand> | |
</additionalBuildcommands> | |
</configuration> | |
</plugin> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-source-plugin</artifactId> | |
<version>2.1.2</version> | |
<executions> | |
<execution> | |
<id>attach-sources</id> | |
<phase>package</phase> | |
<goals> | |
<goal>jar</goal> | |
</goals> | |
</execution> | |
</executions> | |
</plugin> | |
</plugins> | |
<pluginManagement> | |
<plugins> | |
<plugin> | |
<groupId>org.mortbay.jetty</groupId> | |
<artifactId>maven-jetty-plugin</artifactId> | |
<version>6.1.25</version> | |
</plugin> | |
</plugins> | |
</pluginManagement> | |
<extensions> | |
<extension> | |
<groupId>org.springframework.build.aws</groupId> | |
<artifactId>org.springframework.build.aws.maven</artifactId> | |
<version>3.0.0.RELEASE</version> | |
</extension> | |
</extensions> | |
</build> | |
<repositories> | |
<repository> | |
<id>spring-milestone</id> | |
<name>Spring Framework Milestone Repository</name> | |
<url>http://maven.springframework.org/milestone</url> | |
</repository> | |
<repository> | |
<id>spring-release</id> | |
<name>Spring Framework Release Repository</name> | |
<url>http://maven.springframework.org/release</url> | |
</repository> | |
<repository> | |
<!-- necessary for Spring Security 3.1.0.CI-SNAPSHOT dependency --> | |
<id>repository.springframework.maven.snapshot</id> | |
<name>Spring Framework Maven Release Repository</name> | |
<url>http://maven.springframework.org/snapshot</url> | |
</repository> | |
<repository> | |
<id>oauth.googlecode.net</id> | |
<url>http://oauth.googlecode.com/svn/code/maven/</url> | |
</repository> | |
<!-- <repository> | |
<id>java.net</id> | |
<url>http://download.java.net/maven/2</url> | |
</repository>--> | |
</repositories> | |
<pluginRepositories> | |
<pluginRepository> | |
<id>atlassian</id> | |
<url>https://maven.atlassian.com/repository/public</url> | |
</pluginRepository> | |
</pluginRepositories> | |
<distributionManagement> | |
<repository> | |
<id>spring-milestone</id> | |
<name>Spring Milestone Repository</name> | |
<url>s3://maven.springframework.org/milestone</url> | |
</repository> | |
<snapshotRepository> | |
<id>spring-snapshot</id> | |
<name>Spring Snapshot Repository</name> | |
<url>s3://maven.springframework.org/snapshot</url> | |
</snapshotRepository> | |
</distributionManagement> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2002-2011 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.app.web; | |
import static org.junit.Assert.assertEquals; | |
import java.io.StringReader; | |
import java.io.StringWriter; | |
import org.codehaus.jackson.annotate.JsonValue; | |
import org.codehaus.jackson.map.ObjectMapper; | |
import org.junit.Test; | |
import org.springframework.security.openid.OpenIDAuthenticationStatus; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class SerializationTests { | |
@Test | |
public void testOpenIDStatus() throws Exception { | |
OpenIDAuthenticationStatus status = OpenIDAuthenticationStatus.SUCCESS; | |
ObjectMapper mapper = new ObjectMapper(); | |
StringWriter string = new StringWriter(); | |
mapper.writeValue(string, status); | |
System.err.println(string); | |
OpenIDAuthenticationStatus value = mapper.readValue(new StringReader(string.toString()), OpenIDAuthenticationStatus.class); | |
assertEquals(status.toString(), value.toString()); | |
// TODO: these are not equal because of the weird implementation of OpenIDAuthenticationStatus | |
assertEquals(status, value); | |
} | |
@Test | |
public void testCustomStatus() throws Exception { | |
Status status = Status.SUCCESS; | |
ObjectMapper mapper = new ObjectMapper(); | |
mapper.getSerializationConfig().addMixInAnnotations(Status.class, StatusHelper.class); | |
mapper.getDeserializationConfig().addMixInAnnotations(Status.class, StatusHelper.class); | |
StringWriter string = new StringWriter(); | |
mapper.writeValue(string, status); | |
System.err.println(string); | |
Status value = mapper.readValue(new StringReader(string.toString()), Status.class); | |
assertEquals(status.toString(), value.toString()); | |
// TODO: these are not equal because of the weird implementation of Status | |
// assertEquals(status, value); | |
} | |
public static abstract class StatusHelper { | |
public StatusHelper(String value) { | |
} | |
@Override | |
@JsonValue | |
public String toString() { | |
return super.toString(); | |
} | |
} | |
public static class Status { | |
public static Status SUCCESS = new Status("success"); | |
public static Status FAILED = new Status("failed"); | |
private final String name; | |
private Status(String name) { | |
this.name = name; | |
} | |
@Override | |
public String toString() { | |
return name; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
server.port=9005 | |
server.trace=true | |
server.database.0=file:target/hsqldb-data/samples | |
server.dbname.0=samples |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2002-2011 the original author or authors. | |
* | |
* 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 org.cloudfoundry.identity.uaa.web; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import org.openid4java.server.InMemoryServerAssociationStore; | |
import org.openid4java.server.ServerManager; | |
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; | |
/** | |
* @author Dave Syer | |
* | |
*/ | |
public class ServerManagerInitializerInterceptor extends HandlerInterceptorAdapter { | |
private final OpenIdProviderController controller; | |
private ServerManager manager; | |
private String endpointUrl; | |
public void setEndpointUrl(String endpointUrl) { | |
this.endpointUrl = endpointUrl; | |
} | |
public ServerManagerInitializerInterceptor(OpenIdProviderController controller) { | |
this.controller = controller; | |
} | |
@Override | |
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |
initialize(request); | |
return true; | |
} | |
private void initialize(HttpServletRequest request) { | |
request.getSession(true); | |
if (manager == null) { | |
manager = new ServerManager(); | |
manager.setSharedAssociations(new InMemoryServerAssociationStore()); | |
manager.setPrivateAssociations(new InMemoryServerAssociationStore()); | |
if(endpointUrl != null) { | |
manager.setOPEndpointUrl(endpointUrl); | |
} | |
else { | |
manager.setOPEndpointUrl(request.getScheme() + "://" + request.getServerName() + ":" | |
+ request.getServerPort() + request.getContextPath() + "/openid/provider"); | |
} | |
controller.setServerManager(manager); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.app.web; | |
import java.io.IOException; | |
import java.io.UnsupportedEncodingException; | |
import java.net.HttpURLConnection; | |
import java.net.URI; | |
import java.net.URISyntaxException; | |
import java.net.URLDecoder; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
import org.junit.Assume; | |
import org.junit.internal.AssumptionViolatedException; | |
import org.junit.rules.TestWatchman; | |
import org.junit.runners.model.FrameworkMethod; | |
import org.junit.runners.model.Statement; | |
import org.springframework.http.HttpEntity; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpMethod; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.http.client.ClientHttpRequest; | |
import org.springframework.http.client.ClientHttpResponse; | |
import org.springframework.http.client.SimpleClientHttpRequestFactory; | |
import org.springframework.util.LinkedMultiValueMap; | |
import org.springframework.util.MultiValueMap; | |
import org.springframework.web.client.RequestCallback; | |
import org.springframework.web.client.ResponseErrorHandler; | |
import org.springframework.web.client.ResponseExtractor; | |
import org.springframework.web.client.RestClientException; | |
import org.springframework.web.client.RestTemplate; | |
import org.springframework.web.util.UriTemplate; | |
import org.springframework.web.util.UriUtils; | |
/** | |
* <p> | |
* A rule that prevents integration tests from failing if the server application is not running or not accessible. If | |
* the server is not running in the background all the tests here will simply be skipped because of a violated | |
* assumption (showing as successful). Usage: | |
* </p> | |
* | |
* <pre> | |
* @Rule public static BrokerRunning brokerIsRunning = BrokerRunning.isRunning(); | |
* | |
* @Test public void testSendAndReceive() throws Exception { // ... test using RabbitTemplate etc. } | |
* </pre> | |
* <p> | |
* The rule can be declared as static so that it only has to check once for all tests in the enclosing test case, but | |
* there isn't a lot of overhead in making it non-static. | |
* </p> | |
* | |
* @see Assume | |
* @see AssumptionViolatedException | |
* | |
* @author Dave Syer | |
* | |
*/ | |
public class ServerRunning extends TestWatchman { | |
private static Log logger = LogFactory.getLog(ServerRunning.class); | |
// Static so that we only test once on failure: speeds up test suite | |
private static Map<Integer, Boolean> serverOnline = new HashMap<Integer, Boolean>(); | |
// Static so that we only test once on failure | |
private static Map<Integer, Boolean> serverOffline = new HashMap<Integer, Boolean>(); | |
private final boolean assumeOnline; | |
private static int DEFAULT_PORT = 8080; | |
private static String DEFAULT_HOST = "localhost"; | |
private int port; | |
private String hostName = DEFAULT_HOST; | |
private RestTemplate client; | |
/** | |
* @return a new rule that assumes an existing running broker | |
*/ | |
public static ServerRunning isRunning() { | |
return new ServerRunning(true); | |
} | |
/** | |
* @return a new rule that assumes there is no existing broker | |
*/ | |
public static ServerRunning isNotRunning() { | |
return new ServerRunning(false); | |
} | |
private ServerRunning(boolean assumeOnline) { | |
this.assumeOnline = assumeOnline; | |
setPort(DEFAULT_PORT); | |
} | |
/** | |
* @param port the port to set | |
*/ | |
public void setPort(int port) { | |
this.port = port; | |
if (!serverOffline.containsKey(port)) { | |
serverOffline.put(port, true); | |
} | |
if (!serverOnline.containsKey(port)) { | |
serverOnline.put(port, true); | |
} | |
client = getRestTemplate(); | |
} | |
/** | |
* @param hostName the hostName to set | |
*/ | |
public void setHostName(String hostName) { | |
this.hostName = hostName; | |
} | |
@Override | |
public Statement apply(Statement base, FrameworkMethod method, Object target) { | |
// Check at the beginning, so this can be used as a static field | |
if (assumeOnline) { | |
Assume.assumeTrue(serverOnline.get(port)); | |
} | |
else { | |
Assume.assumeTrue(serverOffline.get(port)); | |
} | |
RestTemplate client = new RestTemplate(); | |
boolean online = false; | |
try { | |
client.getForEntity(new UriTemplate(getUrl("/app/openid")).toString(), String.class); | |
online = true; | |
logger.info("Basic connectivity test passed"); | |
} | |
catch (RestClientException e) { | |
logger.warn(String.format( | |
"Not executing tests because basic connectivity test failed for hostName=%s, port=%d", hostName, | |
port), e); | |
if (assumeOnline) { | |
Assume.assumeNoException(e); | |
} | |
} | |
finally { | |
if (online) { | |
serverOffline.put(port, false); | |
if (!assumeOnline) { | |
Assume.assumeTrue(serverOffline.get(port)); | |
} | |
} | |
else { | |
serverOnline.put(port, false); | |
} | |
} | |
return super.apply(base, method, target); | |
} | |
public String getBaseUrl() { | |
return "http://" + hostName + ":" + port; | |
} | |
public String getUrl(String path) { | |
try { | |
if (path.startsWith("http:")) { | |
return path; // URLDecoder.decode(path, "UTF-8"); | |
} | |
if (!path.startsWith("/")) { | |
path = "/" + path; | |
} | |
return URLDecoder.decode("http://" + hostName + ":" + port + path, "UTF-8"); | |
} | |
catch (UnsupportedEncodingException e) { | |
throw new IllegalStateException("Cannot decode path", e); | |
} | |
} | |
public URI getUri(String path) { | |
try { | |
return new URI(getUrl(path)); | |
} | |
catch (URISyntaxException e) { | |
throw new IllegalStateException("Cannot decode path", e); | |
} | |
} | |
public ResponseEntity<String> getForString(String path, final HttpHeaders headers) { | |
HttpEntity<Void> request = new HttpEntity<Void>((Void) null, headers); | |
URI location = getUri(path); | |
logger.debug("Request location: " + location); | |
ResponseEntity<String> result = client.exchange(location, HttpMethod.GET, request, String.class); | |
List<String> cookies = result.getHeaders().get("Set-Cookie"); | |
if (cookies != null && !cookies.isEmpty()) { | |
try { | |
headers.set("Cookie", cookies.get(0)); | |
} catch (Exception e) { | |
logger.error("Could not set cookie on input headers"); | |
} | |
} | |
logger.debug("Result status: " + result.getStatusCode()); | |
logger.debug("Result headers: " + result.getHeaders()); | |
return result; | |
} | |
public ResponseEntity<Void> getForResponse(String path, final HttpHeaders headers) { | |
HttpEntity<Void> request = new HttpEntity<Void>((Void) null, headers); | |
URI location = getUri(path); | |
logger.debug("Request location: " + location); | |
logger.debug("Request headers: " + headers); | |
ResponseEntity<Void> result = client.exchange(location, HttpMethod.GET, request, null); | |
List<String> cookies = result.getHeaders().get("Set-Cookie"); | |
if (cookies != null && !cookies.isEmpty()) { | |
try { | |
headers.set("Cookie", cookies.get(0)); | |
} catch (Exception e) { | |
logger.error("Could not set cookie on input headers"); | |
} | |
} | |
logger.debug("Result status: " + result.getStatusCode()); | |
logger.debug("Result headers: " + result.getHeaders()); | |
return result; | |
} | |
public ResponseEntity<Void> postForRedirect(String path, HttpHeaders headers, MultiValueMap<String, String> params) { | |
HttpHeaders actualHeaders = new HttpHeaders(); | |
actualHeaders.putAll(headers); | |
actualHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | |
URI location = getUri(path); | |
logger.debug("Request location: " + location); | |
logger.debug("Request headers: " + actualHeaders); | |
ResponseEntity<Void> exchange = client.exchange(location, HttpMethod.POST, | |
new HttpEntity<MultiValueMap<String, String>>(params, actualHeaders), null); | |
logger.debug("Result status: " + exchange.getStatusCode()); | |
logger.debug("Result headers: " + exchange.getHeaders()); | |
if (exchange.getStatusCode() != HttpStatus.FOUND) { | |
throw new IllegalStateException("Invalid response from server"); | |
} | |
location = getUri(exchange.getHeaders().getLocation().toString()); | |
List<String> cookies = exchange.getHeaders().get("Set-Cookie"); | |
if (cookies != null && !cookies.isEmpty()) { | |
actualHeaders.set("Cookie", cookies.get(0)); | |
} | |
actualHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
logger.debug("Request location: " + location); | |
logger.debug("Request headers: " + actualHeaders); | |
ResponseEntity<Void> result = client.exchange(location, HttpMethod.GET, new HttpEntity<Void>(null, | |
actualHeaders), null); | |
logger.debug("Result status: " + result.getStatusCode()); | |
logger.debug("Result headers: " + result.getHeaders()); | |
return result; | |
} | |
public ResponseEntity<String> postForPage(String path, HttpHeaders headers, MultiValueMap<String, String> params) { | |
HttpHeaders actualHeaders = new HttpHeaders(); | |
actualHeaders.putAll(headers); | |
actualHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | |
URI location = getUri(path); | |
logger.debug("Request location: " + location); | |
logger.debug("Request headers: " + actualHeaders); | |
ResponseEntity<Void> exchange = client.exchange(location, HttpMethod.POST, | |
new HttpEntity<MultiValueMap<String, String>>(params, actualHeaders), null); | |
logger.debug("Result status: " + exchange.getStatusCode()); | |
logger.debug("Result headers: " + exchange.getHeaders()); | |
if (exchange.getStatusCode() != HttpStatus.FOUND) { | |
throw new IllegalStateException("Invalid response from server"); | |
} | |
location = getUri(exchange.getHeaders().getLocation().toString()); | |
List<String> cookies = exchange.getHeaders().get("Set-Cookie"); | |
if (cookies != null && !cookies.isEmpty()) { | |
actualHeaders.set("Cookie", cookies.get(0)); | |
try { | |
headers.set("Cookie", cookies.get(0)); | |
} catch (Exception e) { | |
logger.error("Could noit set cookie on input headers"); | |
} | |
} | |
actualHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
logger.debug("Request location: " + location); | |
logger.debug("Request headers: " + actualHeaders); | |
ResponseEntity<String> response = client.exchange(location, HttpMethod.GET, new HttpEntity<Void>(null, | |
actualHeaders), String.class); | |
logger.debug("Result status: " + response.getStatusCode()); | |
logger.debug("Result headers: " + response.getHeaders()); | |
return response; | |
} | |
public HttpStatus getStatusCode(String path, final HttpHeaders headers) { | |
RequestCallback requestCallback = new NullRequestCallback(); | |
if (headers != null) { | |
requestCallback = new RequestCallback() { | |
public void doWithRequest(ClientHttpRequest request) throws IOException { | |
request.getHeaders().putAll(headers); | |
} | |
}; | |
} | |
return client.execute(getUri(path), HttpMethod.GET, requestCallback, | |
new ResponseExtractor<ResponseEntity<String>>() { | |
public ResponseEntity<String> extractData(ClientHttpResponse response) throws IOException { | |
return new ResponseEntity<String>(response.getStatusCode()); | |
} | |
}).getStatusCode(); | |
} | |
public HttpStatus getStatusCode(String path) { | |
return getStatusCode(path, null); | |
} | |
public RestTemplate getRestTemplate() { | |
RestTemplate client = new RestTemplate(); | |
client.setRequestFactory(new SimpleClientHttpRequestFactory() { | |
@Override | |
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { | |
super.prepareConnection(connection, httpMethod); | |
connection.setInstanceFollowRedirects(false); | |
} | |
}); | |
client.setErrorHandler(new ResponseErrorHandler() { | |
// Pass errors through in response entity for status code analysis | |
public boolean hasError(ClientHttpResponse response) throws IOException { | |
return false; | |
} | |
public void handleError(ClientHttpResponse response) throws IOException { | |
} | |
}); | |
return client; | |
} | |
public UriBuilder buildUri(String url) { | |
return UriBuilder.fromUri(url.startsWith("http:") ? url : getUrl(url)); | |
} | |
private static final class NullRequestCallback implements RequestCallback { | |
public void doWithRequest(ClientHttpRequest request) throws IOException { | |
} | |
} | |
public static class UriBuilder { | |
private final String url; | |
private MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>(); | |
public UriBuilder(String url) { | |
this.url = url; | |
} | |
public static UriBuilder fromUri(String url) { | |
return new UriBuilder(url); | |
} | |
public UriBuilder queryParam(String key, String value) { | |
params.add(key, value); | |
return this; | |
} | |
public URI build() { | |
StringBuilder builder = new StringBuilder(url); | |
try { | |
if (!params.isEmpty()) { | |
builder.append("?"); | |
boolean first = true; | |
for (String key : params.keySet()) { | |
if (!first) { | |
builder.append("&"); | |
} | |
else { | |
first = false; | |
} | |
for (String value : params.get(key)) { | |
builder.append(key + "=" + UriUtils.encodeQueryParam(value, "UTF-8")); | |
} | |
} | |
} | |
return new URI(builder.toString()); | |
} | |
catch (UnsupportedEncodingException ex) { | |
// should not happen, UTF-8 is always supported | |
throw new IllegalStateException(ex); | |
} | |
catch (URISyntaxException ex) { | |
throw new IllegalArgumentException("Could not create URI from [" + builder + "]: " + ex, ex); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.uaa.web; | |
import java.io.IOException; | |
import java.io.UnsupportedEncodingException; | |
import java.net.URI; | |
import java.net.URISyntaxException; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
import org.apache.http.client.HttpClient; | |
import org.apache.http.client.params.ClientPNames; | |
import org.junit.Assume; | |
import org.junit.internal.AssumptionViolatedException; | |
import org.junit.rules.TestWatchman; | |
import org.junit.runners.model.FrameworkMethod; | |
import org.junit.runners.model.Statement; | |
import org.springframework.http.HttpEntity; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpMethod; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.http.client.ClientHttpRequest; | |
import org.springframework.http.client.ClientHttpResponse; | |
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; | |
import org.springframework.util.LinkedMultiValueMap; | |
import org.springframework.util.MultiValueMap; | |
import org.springframework.web.client.RequestCallback; | |
import org.springframework.web.client.ResponseErrorHandler; | |
import org.springframework.web.client.ResponseExtractor; | |
import org.springframework.web.client.RestClientException; | |
import org.springframework.web.client.RestTemplate; | |
import org.springframework.web.util.UriTemplate; | |
import org.springframework.web.util.UriUtils; | |
/** | |
* <p> | |
* A rule that prevents integration tests from failing if the server application is not running or not accessible. If | |
* the server is not running in the background all the tests here will simply be skipped because of a violated | |
* assumption (showing as successful). Usage: | |
* </p> | |
* | |
* <pre> | |
* @Rule public static BrokerRunning brokerIsRunning = BrokerRunning.isRunning(); | |
* | |
* @Test public void testSendAndReceive() throws Exception { // ... test using RabbitTemplate etc. } | |
* </pre> | |
* <p> | |
* The rule can be declared as static so that it only has to check once for all tests in the enclosing test case, but | |
* there isn't a lot of overhead in making it non-static. | |
* </p> | |
* | |
* @see Assume | |
* @see AssumptionViolatedException | |
* | |
* @author Dave Syer | |
* | |
*/ | |
public class ServerRunning extends TestWatchman { | |
private static Log logger = LogFactory.getLog(ServerRunning.class); | |
// Static so that we only test once on failure: speeds up test suite | |
private static Map<Integer, Boolean> serverOnline = new HashMap<Integer, Boolean>(); | |
// Static so that we only test once on failure | |
private static Map<Integer, Boolean> serverOffline = new HashMap<Integer, Boolean>(); | |
private final boolean assumeOnline; | |
private static int DEFAULT_PORT = 8080; | |
private static String DEFAULT_HOST = "localhost"; | |
private int port; | |
private String hostName = DEFAULT_HOST; | |
private RestTemplate client; | |
/** | |
* @return a new rule that assumes an existing running broker | |
*/ | |
public static ServerRunning isRunning() { | |
return new ServerRunning(true); | |
} | |
/** | |
* @return a new rule that assumes there is no existing broker | |
*/ | |
public static ServerRunning isNotRunning() { | |
return new ServerRunning(false); | |
} | |
private ServerRunning(boolean assumeOnline) { | |
this.assumeOnline = assumeOnline; | |
setPort(DEFAULT_PORT); | |
} | |
/** | |
* @param port the port to set | |
*/ | |
public void setPort(int port) { | |
this.port = port; | |
if (!serverOffline.containsKey(port)) { | |
serverOffline.put(port, true); | |
} | |
if (!serverOnline.containsKey(port)) { | |
serverOnline.put(port, true); | |
} | |
client = getRestTemplate(); | |
} | |
/** | |
* @param hostName the hostName to set | |
*/ | |
public void setHostName(String hostName) { | |
this.hostName = hostName; | |
} | |
@Override | |
public Statement apply(Statement base, FrameworkMethod method, Object target) { | |
// Check at the beginning, so this can be used as a static field | |
if (assumeOnline) { | |
Assume.assumeTrue(serverOnline.get(port)); | |
} | |
else { | |
Assume.assumeTrue(serverOffline.get(port)); | |
} | |
RestTemplate client = new RestTemplate(); | |
boolean online = false; | |
try { | |
client.getForEntity(new UriTemplate(getUrl("/auth/login")).toString(), String.class); | |
online = true; | |
logger.info("Basic connectivity test passed"); | |
} | |
catch (RestClientException e) { | |
logger.warn(String.format( | |
"Not executing tests because basic connectivity test failed for hostName=%s, port=%d", hostName, | |
port), e); | |
if (assumeOnline) { | |
Assume.assumeNoException(e); | |
} | |
} | |
finally { | |
if (online) { | |
serverOffline.put(port, false); | |
if (!assumeOnline) { | |
Assume.assumeTrue(serverOffline.get(port)); | |
} | |
} | |
else { | |
serverOnline.put(port, false); | |
} | |
} | |
return super.apply(base, method, target); | |
} | |
public String getBaseUrl() { | |
return "http://" + hostName + ":" + port; | |
} | |
public String getUrl(String path) { | |
if (path.startsWith("http:")) { | |
return path; | |
} | |
if (!path.startsWith("/")) { | |
path = "/" + path; | |
} | |
return "http://" + hostName + ":" + port + path; | |
} | |
public ResponseEntity<String> postForString(String path, MultiValueMap<String, String> formData) { | |
return postForString(path, formData, new HttpHeaders()); | |
} | |
@SuppressWarnings("rawtypes") | |
public ResponseEntity<Map> postForMap(String path, MultiValueMap<String, String> formData) { | |
return postForMap(path, formData, new HttpHeaders()); | |
} | |
@SuppressWarnings("rawtypes") | |
public ResponseEntity<Map> postForMap(String path, MultiValueMap<String, String> formData, HttpHeaders headers) { | |
if (headers.getContentType() == null) { | |
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | |
} | |
return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity<MultiValueMap<String, String>>(formData, | |
headers), Map.class); | |
} | |
public ResponseEntity<String> postForString(String path, MultiValueMap<String, String> formData, HttpHeaders headers) { | |
if (headers.getContentType() == null) { | |
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | |
} | |
return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity<MultiValueMap<String, String>>(formData, | |
headers), String.class); | |
} | |
public ResponseEntity<String> getForString(String path) { | |
return client.exchange(getUrl(path), HttpMethod.GET, new HttpEntity<Void>((Void) null), String.class); | |
} | |
public ResponseEntity<String> getForString(String path, final HttpHeaders headers) { | |
HttpEntity<Void> request = new HttpEntity<Void>((Void) null, headers); | |
return client.exchange(getUrl(path), HttpMethod.GET, request, String.class); | |
} | |
public ResponseEntity<Void> getForResponse(String path, final HttpHeaders headers) { | |
HttpEntity<Void> request = new HttpEntity<Void>((Void) null, headers); | |
return client.exchange(getUrl(path), HttpMethod.GET, request, null); | |
} | |
public ResponseEntity<Void> postForRedirect(String path, HttpHeaders headers, MultiValueMap<String, String> params) { | |
HttpHeaders actualHeaders = new HttpHeaders(); | |
actualHeaders.putAll(headers); | |
actualHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | |
ResponseEntity<Void> exchange = client.exchange(getUrl(path), HttpMethod.POST, | |
new HttpEntity<MultiValueMap<String, String>>(params, actualHeaders), null); | |
if (exchange.getStatusCode() != HttpStatus.FOUND) { | |
throw new IllegalStateException("Invalid response from server"); | |
} | |
String location = exchange.getHeaders().getLocation().toString(); | |
List<String> cookies = exchange.getHeaders().get("Set-Cookie"); | |
if (cookies != null && !cookies.isEmpty()) { | |
actualHeaders.add("Cookie", cookies.get(0)); | |
} | |
actualHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
logger.debug("Request location: " + location); | |
logger.debug("Request headers: " + actualHeaders); | |
ResponseEntity<Void> result = client.exchange(location, HttpMethod.GET, new HttpEntity<Void>(null, | |
actualHeaders), null); | |
logger.debug("Result status: " + result.getStatusCode()); | |
logger.debug("Result headers: " + result.getHeaders()); | |
return result; | |
} | |
public HttpStatus getStatusCode(String path, final HttpHeaders headers) { | |
RequestCallback requestCallback = new NullRequestCallback(); | |
if (headers != null) { | |
requestCallback = new RequestCallback() { | |
public void doWithRequest(ClientHttpRequest request) throws IOException { | |
request.getHeaders().putAll(headers); | |
} | |
}; | |
} | |
return client.execute(getUrl(path), HttpMethod.GET, requestCallback, | |
new ResponseExtractor<ResponseEntity<String>>() { | |
public ResponseEntity<String> extractData(ClientHttpResponse response) throws IOException { | |
return new ResponseEntity<String>(response.getStatusCode()); | |
} | |
}).getStatusCode(); | |
} | |
public HttpStatus getStatusCode(String path) { | |
return getStatusCode(getUrl(path), null); | |
} | |
public RestTemplate getRestTemplate() { | |
RestTemplate client = new RestTemplate(); | |
client.setRequestFactory(new HttpComponentsClientHttpRequestFactory() { | |
@Override | |
public HttpClient getHttpClient() { | |
HttpClient client = super.getHttpClient(); | |
client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); | |
return client; | |
} | |
}); | |
client.setErrorHandler(new ResponseErrorHandler() { | |
// Pass errors through in response entity for status code analysis | |
public boolean hasError(ClientHttpResponse response) throws IOException { | |
return false; | |
} | |
public void handleError(ClientHttpResponse response) throws IOException { | |
} | |
}); | |
return client; | |
} | |
public UriBuilder buildUri(String url) { | |
return UriBuilder.fromUri(url.startsWith("http:") ? url : getUrl(url)); | |
} | |
private static final class NullRequestCallback implements RequestCallback { | |
public void doWithRequest(ClientHttpRequest request) throws IOException { | |
} | |
} | |
public static class UriBuilder { | |
private final String url; | |
private MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>(); | |
public UriBuilder(String url) { | |
this.url = url; | |
} | |
public static UriBuilder fromUri(String url) { | |
return new UriBuilder(url); | |
} | |
public UriBuilder queryParam(String key, String value) { | |
params.add(key, value); | |
return this; | |
} | |
public URI build() { | |
StringBuilder builder = new StringBuilder(url); | |
try { | |
if (!params.isEmpty()) { | |
builder.append("?"); | |
boolean first = true; | |
for (String key : params.keySet()) { | |
if (!first) { | |
builder.append("&"); | |
} | |
else { | |
first = false; | |
} | |
for (String value : params.get(key)) { | |
builder.append(key + "=" + UriUtils.encodeQueryParam(value, "UTF-8")); | |
} | |
} | |
} | |
return new URI(builder.toString()); | |
} | |
catch (UnsupportedEncodingException ex) { | |
// should not happen, UTF-8 is always supported | |
throw new IllegalStateException(ex); | |
} | |
catch (URISyntaxException ex) { | |
throw new IllegalArgumentException("Could not create URI from [" + builder + "]: " + ex, ex); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:sec="http://www.springframework.org/schema/security" | |
xmlns:oauth="http://www.springframework.org/schema/security/oauth2" | |
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd | |
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd | |
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd | |
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> | |
<http pattern="/denied" security="none" xmlns="http://www.springframework.org/schema/security" /> | |
<!-- TODO: make an access denied view that tells me something useful --> | |
<http access-denied-page="/denied" entry-point-ref="authenticationEntryPoint" access-decision-manager-ref="accessDecisionManager" | |
xmlns="http://www.springframework.org/schema/security"> | |
<intercept-url pattern="/photos/**" access="SCOPE_READ_PHOTOS" /> | |
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" /> | |
<custom-filter ref="oauth2ServiceFilter" before="EXCEPTION_TRANSLATION_FILTER" /> | |
<anonymous /> | |
</http> | |
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans"> | |
<constructor-arg> | |
<list> | |
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" /> | |
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" /> | |
</list> | |
</constructor-arg> | |
</bean> | |
<authentication-manager xmlns="http://www.springframework.org/schema/security" /> | |
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint" | |
xmlns="http://www.springframework.org/schema/beans"> | |
<property name="loginFormUrl" value="${auth.url}" /> | |
</bean> | |
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" | |
xmlns="http://www.springframework.org/schema/beans"> | |
<property name="location"> | |
<value>#{T(java.lang.System).getenv('VCAP_APPLICATION')==null ? 'classpath:/application.properties' : | |
'classpath:/application-cloud.properties'} | |
</value> | |
</property> | |
</bean> | |
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" xmlns="http://www.springframework.org/schema/beans"> | |
<property name="driverClassName" value="${jdbc.driver}" /> | |
<property name="url" value="${jdbc.url}" /> | |
<property name="username" value="${jdbc.user}" /> | |
<property name="password" value="${jdbc.password}" /> | |
<property name="testWhileIdle" value="${jdbc.testWhileIdle}" /> | |
<property name="validationQuery" value="${jdbc.validationQuery}" /> | |
</bean> | |
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.RandomValueTokenServices"> | |
<property name="tokenStore"> | |
<bean class="org.springframework.security.oauth2.provider.token.JdbcTokenStore"> | |
<constructor-arg ref="dataSource" /> | |
</bean> | |
</property> | |
<property name="supportRefreshToken" value="true" /> | |
</bean> | |
<oauth:resource-server id="oauth2ServiceFilter" resource-id="api" token-services-ref="tokenServices"/> | |
<mvc:annotation-driven /> | |
<mvc:default-servlet-handler /> | |
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> | |
<property name="mediaTypes"> | |
<map> | |
<entry key="json" value="application/json" /> | |
<entry key="xml" value="application/xml" /> | |
</map> | |
</property> | |
<property name="defaultViews"> | |
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> | |
</property> | |
</bean> | |
<bean id="photoController" class="org.cloudfoundry.identity.api.web.mvc.PhotoController"> | |
<property name="photoService" ref="photoServices" /> | |
</bean> | |
<bean id="photoServices" class="org.cloudfoundry.identity.api.service.PhotoServiceImpl"> | |
<property name="photos"> | |
<list> | |
<bean class="org.cloudfoundry.identity.api.PhotoInfo"> | |
<property name="id" value="1" /> | |
<property name="name" value="photo1.jpg" /> | |
<property name="userId" value="marissa" /> | |
<property name="resourceURL" value="/org/cloudfoundry/identity/api/web/impl/resources/photo1.jpg" /> | |
</bean> | |
<bean class="org.cloudfoundry.identity.api.PhotoInfo"> | |
<property name="id" value="2" /> | |
<property name="name" value="photo2.jpg" /> | |
<property name="userId" value="[email protected]" /> | |
<property name="resourceURL" value="/org/cloudfoundry/identity/api/web/impl/resources/photo2.jpg" /> | |
</bean> | |
<bean class="org.cloudfoundry.identity.api.PhotoInfo"> | |
<property name="id" value="3" /> | |
<property name="name" value="photo3.jpg" /> | |
<property name="userId" value="marissa" /> | |
<property name="resourceURL" value="/org/cloudfoundry/identity/api/web/impl/resources/photo3.jpg" /> | |
</bean> | |
<bean class="org.cloudfoundry.identity.api.PhotoInfo"> | |
<property name="id" value="4" /> | |
<property name="name" value="photo4.jpg" /> | |
<property name="userId" value="[email protected]" /> | |
<property name="resourceURL" value="/org/cloudfoundry/identity/api/web/impl/resources/photo4.jpg" /> | |
</bean> | |
<bean class="org.cloudfoundry.identity.api.PhotoInfo"> | |
<property name="id" value="5" /> | |
<property name="name" value="photo5.jpg" /> | |
<property name="userId" value="marissa" /> | |
<property name="resourceURL" value="/org/cloudfoundry/identity/api/web/impl/resources/photo5.jpg" /> | |
</bean> | |
<bean class="org.cloudfoundry.identity.api.PhotoInfo"> | |
<property name="id" value="6" /> | |
<property name="name" value="photo6.jpg" /> | |
<property name="userId" value="paul" /> | |
<property name="resourceURL" value="/org/cloudfoundry/identity/api/web/impl/resources/photo6.jpg" /> | |
</bean> | |
</list> | |
</property> | |
</bean> | |
</beans> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:oauth="http://www.springframework.org/schema/security/oauth2" | |
xmlns:context="http://www.springframework.org/schema/context" xmlns:sec="http://www.springframework.org/schema/security" | |
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd | |
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd | |
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd | |
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd | |
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> | |
<sec:http pattern="/loggedout.jsp" security="none" /> | |
<sec:http pattern="/login_error.jsp" security="none" /> | |
<sec:http pattern="/resources/**" security="none" /> | |
<sec:http pattern="/favicon.ico" security="none" /> | |
<http xmlns="http://www.springframework.org/schema/security"> | |
<intercept-url pattern="/**" access="ROLE_USER" /> | |
<logout logout-success-url="/loggedout.jsp" /> | |
<openid-login login-page="#{loginController.loginUrl}" login-processing-url="/login" user-service-ref="registeringUserService" | |
authentication-failure-url="/login_error.jsp"> | |
<attribute-exchange identifier-match=".*"> | |
<openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" /> | |
<openid-attribute name="fullname" type="http://schema.openid.net/namePerson" required="true" /> | |
</attribute-exchange> | |
</openid-login> | |
<custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" /> | |
</http> | |
<sec:authentication-manager alias="authenticationManager" /> | |
<!--apply the oauth client context --> | |
<oauth:client id="oauth2ClientFilter" /> | |
<bean id="registeringUserService" class="org.cloudfoundry.identity.openid.user.CustomUserDetailsService" /> | |
<mvc:resources location="/resources/" mapping="/resources/**" /> | |
<mvc:annotation-driven /> | |
<mvc:default-servlet-handler /> | |
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> | |
<property name="mediaTypes"> | |
<map> | |
<entry key="json" value="application/json" /> | |
</map> | |
</property> | |
<property name="defaultViews"> | |
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> | |
</property> | |
</bean> | |
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> | |
<property name="prefix" value="/" /> | |
<property name="suffix" value=".jsp" /> | |
</bean> | |
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" xmlns="http://www.springframework.org/schema/beans"> | |
<property name="location"> | |
<value>#{T(java.lang.System).getenv('VCAP_APPLICATION')==null ? 'classpath:/application.properties' : | |
'classpath:/application-cloud.properties'} | |
</value> | |
</property> | |
</bean> | |
<bean id="loginController" class="org.cloudfoundry.identity.app.web.LoginController"> | |
<property name="openidProviderUrl" value="${openidProviderUrl}" /> | |
</bean> | |
<bean id="photoController" class="org.cloudfoundry.identity.app.web.PhotoController"> | |
<property name="restTemplate"> | |
<bean class="org.springframework.security.oauth2.client.OAuth2RestTemplate"> | |
<constructor-arg ref="api" /> | |
</bean> | |
</property> | |
<property name="photoListUrl" value="${photoListUrl}" /> | |
<property name="photoUrlPattern" value="${photoUrlPattern}" /> | |
<property name="photoUrlPassthruPattern" value="${photoUrlPassthruPattern}" /> | |
</bean> | |
<!--define an oauth 2 resource for api access --> | |
<oauth:resource id="api" type="authorization_code" client-id="app" client-secret="appclientsecret" | |
access-token-uri="${accessTokenUri}" user-authorization-uri="${userAuthorizationUri}" scope="read_photos" /> | |
</beans> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" | |
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" | |
xmlns:sec="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2" | |
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd | |
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd | |
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd | |
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd | |
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> | |
<sec:http pattern="/resources/**" security="none" /> | |
<sec:http pattern="/favicon.ico" security="none" /> | |
<sec:http pattern="/openid" security="none" /> | |
<sec:http pattern="/openid/users/*" security="none" /> | |
<http pattern="/oauth/token" create-session="never" authentication-manager-ref="clientAuthenticationManager" | |
xmlns="http://www.springframework.org/schema/security"> | |
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" /> | |
<anonymous enabled="false" /> | |
<http-basic /> | |
</http> | |
<http access-denied-page="/" xmlns="http://www.springframework.org/schema/security"> | |
<!-- machine API access to the authorization process itself is allowed --> | |
<intercept-url pattern="/openid/provider" access="IS_AUTHENTICATED_ANONYMOUSLY" /> | |
<intercept-url pattern="/openid/**" access="ROLE_USER" /> | |
<intercept-url pattern="/login**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> | |
<intercept-url pattern="/oauth/**" access="ROLE_USER" /> | |
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" /> | |
<form-login authentication-failure-url="/login" login-page="/login" login-processing-url="/login.do" | |
username-parameter="username" password-parameter="password" /> | |
<anonymous /> | |
<logout logout-success-url="/" logout-url="/logout.do" /> | |
</http> | |
<authentication-manager erase-credentials="false" alias="authenticationManager" | |
xmlns="http://www.springframework.org/schema/security"> | |
<!-- provider for tests --> | |
<authentication-provider> | |
<user-service> | |
<user name="marissa" authorities="ROLE_USER" password="koala" /> | |
</user-service> | |
</authentication-provider> | |
</authentication-manager> | |
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.filter.ClientCredentialsTokenEndpointFilter"> | |
<property name="authenticationManager" ref="clientAuthenticationManager" /> | |
</bean> | |
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security"> | |
<authentication-provider user-service-ref="clientDetailsUserService" /> | |
</authentication-manager> | |
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> | |
<constructor-arg ref="clientDetails" /> | |
</bean> | |
<context:property-placeholder location="classpath:/application.properties" /> | |
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> | |
<property name="driverClassName" value="${jdbc.driver}" /> | |
<property name="url" value="${jdbc.url}" /> | |
<property name="username" value="${jdbc.user}" /> | |
<property name="password" value="${jdbc.password}" /> | |
<property name="testWhileIdle" value="${jdbc.testWhileIdle}" /> | |
<property name="validationQuery" value="${jdbc.validationQuery}" /> | |
</bean> | |
<bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer"> | |
<property name="databasePopulator"> | |
<bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator"> | |
<property name="scripts" | |
value="classpath:/create-schema#{T(java.lang.System).getenv('VCAP_APPLICATION')==null ? '' : '-mysql'}.sql" /> | |
<property name="ignoreFailedDrops" value="true" /> | |
</bean> | |
</property> | |
<property name="dataSource" ref="dataSource" /> | |
</bean> | |
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.RandomValueTokenServices"> | |
<property name="tokenStore" ref="tokenStore" /> | |
<property name="supportRefreshToken" value="true" /> | |
</bean> | |
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.JdbcTokenStore"> | |
<constructor-arg ref="dataSource" /> | |
</bean> | |
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices"> | |
<oauth:authorization-code /> | |
<oauth:implicit /> | |
<oauth:refresh-token /> | |
<oauth:client-credentials /> | |
<oauth:password /> | |
</oauth:authorization-server> | |
<oauth:client-details-service id="clientDetails"> | |
<oauth:client client-id="app" authorized-grant-types="password,authorization_code,refresh_token,implicit" | |
scope="read_photos" authorities="ROLE_GUEST" secret="appclientsecret" /> | |
</oauth:client-details-service> | |
<mvc:resources location="/resources/" mapping="/resources/**" /> | |
<mvc:annotation-driven /> | |
<mvc:default-servlet-handler /> | |
<mvc:interceptors> | |
<bean class="org.cloudfoundry.identity.uaa.web.ServerManagerInitializerInterceptor"> | |
<constructor-arg ref="openidController" /> | |
<property name="endpointUrl" value="${endpointUrl}"></property> | |
</bean> | |
</mvc:interceptors> | |
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> | |
<property name="mediaTypes"> | |
<map> | |
<entry key="html" value="text/html" /> | |
<entry key="json" value="application/json" /> | |
</map> | |
</property> | |
<property name="viewResolvers"> | |
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> | |
<property name="prefix" value="/WEB-INF/jsp/" /> | |
<property name="suffix" value=".jsp" /> | |
</bean> | |
</property> | |
<property name="defaultViews"> | |
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> | |
</property> | |
</bean> | |
<!--Basic application beans. --> | |
<bean id="accessConfirmationController" class="org.cloudfoundry.identity.uaa.web.AccessController"> | |
<property name="clientDetailsService" ref="clientDetails" /> | |
</bean> | |
<bean id="openidController" class="org.cloudfoundry.identity.uaa.web.OpenIdProviderController" /> | |
</beans> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:mvc="http://www.springframework.org/schema/mvc" | |
xmlns:oauth="http://www.springframework.org/schema/security/oauth2" | |
xmlns:context="http://www.springframework.org/schema/context" | |
xmlns:sec="http://www.springframework.org/schema/security" | |
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd | |
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd | |
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd | |
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd | |
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> | |
<sec:http pattern="/openid" security="none" /> | |
<sec:http pattern="/loggedout.jsp" security="none" /> | |
<sec:http pattern="/login_error.jsp" security="none" /> | |
<sec:http pattern="/resources/**" security="none" /> | |
<sec:http pattern="/favicon.ico" security="none" /> | |
<http xmlns="http://www.springframework.org/schema/security"> | |
<intercept-url pattern="/**" access="ROLE_USER" /> | |
<logout logout-success-url="/loggedout.jsp"/> | |
<openid-login login-page="#{loginController.loginUrl}" login-processing-url="/login" | |
user-service-ref="registeringUserService" authentication-failure-url="/login_error.jsp"> | |
<attribute-exchange identifier-match=".*"> | |
<openid-attribute name="email" | |
type="http://schema.openid.net/contact/email" required="true" /> | |
<openid-attribute name="fullname" | |
type="http://schema.openid.net/namePerson" required="true" /> | |
</attribute-exchange> | |
</openid-login> | |
</http> | |
<sec:authentication-manager alias="authenticationManager" /> | |
<bean id="registeringUserService" | |
class="org.cloudfoundry.identity.openid.user.CustomUserDetailsService" /> | |
<mvc:resources location="/resources/" mapping="/resources/**" /> | |
<mvc:annotation-driven /> | |
<mvc:default-servlet-handler /> | |
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> | |
<property name="mediaTypes"> | |
<map> | |
<entry key="json" value="application/json" /> | |
</map> | |
</property> | |
<property name="defaultViews"> | |
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/> | |
</property> | |
</bean> | |
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> | |
<property name="prefix" value="/" /> | |
<property name="suffix" value=".jsp" /> | |
</bean> | |
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" xmlns="http://www.springframework.org/schema/beans"> | |
<property name="location"> | |
<value>#{T(java.lang.System).getenv('VCAP_APPLICATION')==null ? 'classpath:/application.properties' : | |
'classpath:/application-cloud.properties'}</value> | |
</property> | |
</bean> | |
<bean id="loginController" class="org.cloudfoundry.identity.app.web.LoginController"> | |
<property name="openidProviderUrl" value="${openidProviderUrl}" /> | |
</bean> | |
</beans> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* CSS Document */ | |
body { | |
font-family: 'Trebuchet MS', Helvetica, sans-serif; | |
font-size: 12px; | |
margin: 0 auto; | |
width: 736px; | |
background: url( 'images/bg.gif' ); | |
} | |
#content { | |
background: #3d3d3d; | |
width: 676px; | |
margin-top: 20px; | |
padding: 0 30px 25px 30px; | |
} | |
a { | |
color: lightblue; | |
text-decoration: none; | |
} | |
a:hover { | |
color: red; | |
text-decoration: none; | |
} | |
h1 { | |
background: url( 'images/header.jpg' ); | |
color: white; | |
height: 36px; | |
width: 721px; | |
margin: 0 0 1em 0; | |
padding-top: 80px; | |
padding-left: 15px; | |
font-size: 1.8em; | |
font-variant: small-caps; | |
} | |
h2 { | |
font-size: 1.2em; | |
margin-left: -10px; | |
padding-top: 20px; | |
font-weight: bold; | |
letter-spacing: .3px; | |
} | |
.error h2 { | |
color: red; | |
font-size: 1.2em; | |
padding-top: 20px; | |
font-weight: bold; | |
letter-spacing: .3px; | |
} | |
.error p { | |
color: red; | |
} | |
p { | |
letter-spacing: .2px; | |
} | |
label { | |
text-indent: 20px; | |
letter-spacing: .2px; | |
padding: 5px 5px 5px 5px; | |
} | |
#footer { | |
font-size: .8em; | |
margin-top: 1em; | |
} | |
#footer a { | |
color: blue; | |
font-weight: bold; | |
font-size: 1em | |
} | |
#footer a:hover { | |
color: red; | |
font-weight: bold; | |
font-size: 1em | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* CSS Document */ | |
body { | |
color: white; | |
font-family: 'Trebuchet MS', Helvetica, sans-serif; | |
font-size: 12px; | |
margin: 0 auto; | |
width: 736px; | |
background: url( 'images/bg.gif' ); | |
} | |
#content { | |
background: #3d3d3d; | |
width: 676px; | |
margin-top: 20px; | |
padding: 0 30px 25px 30px; | |
} | |
a { | |
color: lightblue; | |
text-decoration: none; | |
} | |
a:hover { | |
color: red; | |
text-decoration: none; | |
} | |
h1 { | |
background: url( 'images/header.jpg' ); | |
height: 36px; | |
width: 721px; | |
margin: 0 0 1em 0; | |
padding-top: 80px; | |
padding-left: 15px; | |
font-size: 1.8em; | |
font-variant: small-caps; | |
} | |
h2 { | |
font-size: 1.2em; | |
margin-left: -10px; | |
padding-top: 20px; | |
font-weight: bold; | |
letter-spacing: .3px; | |
} | |
.error h2 { | |
color: red; | |
font-size: 1.2em; | |
padding-top: 20px; | |
font-weight: bold; | |
letter-spacing: .3px; | |
} | |
.error p { | |
color: red; | |
} | |
p { | |
letter-spacing: .2px; | |
} | |
label { | |
text-indent: 20px; | |
letter-spacing: .2px; | |
padding: 5px 5px 5px 5px; | |
} | |
#footer { | |
font-size: .8em; | |
margin-top: 1em; | |
} | |
#footer a { | |
color: #333333; | |
font-weight: bold; | |
font-size: 1em | |
} | |
#footer a:hover { | |
color: red; | |
font-weight: bold; | |
font-size: 1em | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* CSS Document */ | |
body { | |
font-family: 'Trebuchet MS', Helvetica, sans-serif; | |
font-size: 12px; | |
margin: 0 auto; | |
width: 736px; | |
background: url( 'images/bg.gif' ); | |
} | |
#content { | |
background: #3d3d3d; | |
width: 676px; | |
margin-top: 20px; | |
padding: 0 30px 25px 30px; | |
} | |
a { | |
color: lightblue; | |
text-decoration: none; | |
} | |
a:hover { | |
color: red; | |
text-decoration: none; | |
} | |
h1 { | |
background: url( 'images/header.jpg' ); | |
color: yellow; | |
height: 36px; | |
width: 721px; | |
margin: 0 0 1em 0; | |
padding-top: 80px; | |
padding-left: 15px; | |
font-size: 1.8em; | |
font-variant: small-caps; | |
} | |
h2 { | |
font-size: 1.2em; | |
margin-left: -10px; | |
padding-top: 20px; | |
font-weight: bold; | |
letter-spacing: .3px; | |
} | |
.error h2 { | |
color: red; | |
font-size: 1.2em; | |
padding-top: 20px; | |
font-weight: bold; | |
letter-spacing: .3px; | |
} | |
.error p { | |
color: red; | |
} | |
p { | |
letter-spacing: .2px; | |
} | |
label { | |
text-indent: 20px; | |
letter-spacing: .2px; | |
padding: 5px 5px 5px 5px; | |
} | |
#footer { | |
font-size: .8em; | |
margin-top: 1em; | |
} | |
#footer a { | |
color: blue; | |
font-weight: bold; | |
font-size: 1em | |
} | |
#footer a:hover { | |
color: red; | |
font-weight: bold; | |
font-size: 1em | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.uaa.web; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertNotNull; | |
import static org.junit.Assert.assertTrue; | |
import java.net.URI; | |
import java.util.Arrays; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.util.LinkedMultiValueMap; | |
import org.springframework.util.MultiValueMap; | |
/** | |
* @author Ryan Heaton | |
* @author Dave Syer | |
*/ | |
public class TestImplicitProvider { | |
@Rule | |
public ServerRunning serverRunning = ServerRunning.isRunning(); | |
/** | |
* tests the basic implicit provider | |
*/ | |
@Test | |
public void testBasicImplicitProvider() throws Exception { | |
HttpHeaders headers = new HttpHeaders(); | |
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
URI uri = serverRunning.buildUri("/auth/oauth/authorize").queryParam("response_type", "token") | |
.queryParam("client_id", "app").queryParam("client_secret", "appclientsecret") | |
.queryParam("redirect_uri", "http://anywhere").queryParam("scope", "read_photos").build(); | |
ResponseEntity<Void> result = serverRunning.getForResponse(uri.toString(), headers); | |
assertEquals(HttpStatus.FOUND, result.getStatusCode()); | |
String location = result.getHeaders().getLocation().toString(); | |
String cookie = result.getHeaders().getFirst("Set-Cookie"); | |
assertNotNull("Expected cookie in " + result.getHeaders(), cookie); | |
headers.set("Cookie", cookie); | |
ResponseEntity<String> response = serverRunning.getForString(location, headers); | |
// should be directed to the login screen... | |
assertTrue(response.getBody().contains("auth/login.do")); | |
assertTrue(response.getBody().contains("username")); | |
assertTrue(response.getBody().contains("password")); | |
location = "auth/login.do"; | |
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); | |
formData.add("username", "marissa"); | |
formData.add("password", "koala"); | |
result = serverRunning.postForRedirect(location, headers, formData); | |
assertNotNull(result.getHeaders().getLocation()); | |
location = result.getHeaders().getLocation().toString(); | |
assertTrue(location.contains("anywhere")); | |
assertTrue(location.contains("#")); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.uaa.web; | |
import static org.junit.Assert.assertEquals; | |
import java.util.Arrays; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.security.crypto.codec.Base64; | |
import org.springframework.util.LinkedMultiValueMap; | |
import org.springframework.util.MultiValueMap; | |
/** | |
* @author Ryan Heaton | |
* @author Dave Syer | |
*/ | |
public class TestNativeApplicationProfile { | |
@Rule | |
public ServerRunning serverRunning = ServerRunning.isRunning(); | |
/** | |
* tests a happy-day flow of the Resource Owner Password Credentials grant type. | |
* (formerly native application profile). | |
*/ | |
@Test | |
public void testHappyDay() throws Exception { | |
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); | |
formData.add("grant_type", "password"); | |
formData.add("client_id", "app"); | |
formData.add("client_secret", "appclientsecret"); | |
formData.add("username", "marissa"); | |
formData.add("password", "koala"); | |
formData.add("scope", "read_photos"); | |
HttpHeaders headers = new HttpHeaders(); | |
headers.set("Authorization", "Basic " + new String(Base64.encode("app:appclientsecret".getBytes("UTF-8")))); | |
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
ResponseEntity<String> response = serverRunning.postForString("/auth/oauth/token", formData, headers); | |
assertEquals(HttpStatus.OK, response.getStatusCode()); | |
assertEquals("no-store", response.getHeaders().getFirst("Cache-Control")); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.uaa.web; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertFalse; | |
import static org.junit.Assert.assertNotNull; | |
import java.util.Arrays; | |
import java.util.Map; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.security.crypto.codec.Base64; | |
import org.springframework.security.oauth2.common.OAuth2AccessToken; | |
import org.springframework.util.LinkedMultiValueMap; | |
import org.springframework.util.MultiValueMap; | |
/** | |
* @author Ryan Heaton | |
* @author Dave Syer | |
*/ | |
public class TestRefreshTokenSupport { | |
@Rule | |
public ServerRunning serverRunning = ServerRunning.isRunning(); | |
@Test | |
public void testHappyDay() throws Exception { | |
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); | |
formData.add("grant_type", "password"); | |
formData.add("client_id", "app"); | |
formData.add("username", "marissa"); | |
formData.add("password", "koala"); | |
formData.add("scope", "read_photos"); | |
HttpHeaders headers = new HttpHeaders(); | |
headers.set("Authorization", "Basic " + new String(Base64.encode("app:appclientsecret".getBytes("UTF-8")))); | |
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
@SuppressWarnings("rawtypes") | |
ResponseEntity<Map> response = serverRunning.postForMap("/auth/oauth/token", formData, headers ); | |
assertEquals(HttpStatus.OK, response.getStatusCode()); | |
assertEquals("no-store", response.getHeaders().getFirst("Cache-Control")); | |
@SuppressWarnings("unchecked") | |
OAuth2AccessToken accessToken =OAuth2AccessToken.valueOf(response.getBody()); | |
// now use the refresh token to get a new access token. | |
assertNotNull(accessToken.getRefreshToken()); | |
formData = new LinkedMultiValueMap<String, String>(); | |
formData.add("grant_type", "refresh_token"); | |
formData.add("refresh_token", accessToken.getRefreshToken().getValue()); | |
response = serverRunning.postForMap("/auth/oauth/token", formData, headers); | |
assertEquals(HttpStatus.OK, response.getStatusCode()); | |
assertEquals("no-store", response.getHeaders().getFirst("Cache-Control")); | |
@SuppressWarnings("unchecked") | |
OAuth2AccessToken newAccessToken = OAuth2AccessToken.valueOf(response.getBody()); | |
assertFalse(newAccessToken.getValue().equals(accessToken.getValue())); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.cloudfoundry.identity.uaa.web; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertTrue; | |
import java.net.URI; | |
import java.util.Arrays; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.util.LinkedMultiValueMap; | |
import org.springframework.util.MultiValueMap; | |
/** | |
* @author Ryan Heaton | |
* @author Dave Syer | |
*/ | |
public class TestWebServerProfile { | |
@Rule | |
public ServerRunning serverRunning = ServerRunning.isRunning(); | |
/** | |
* tests the basic web server profile | |
*/ | |
@Test | |
public void testBasicWebServerProfile() throws Exception { | |
HttpHeaders headers = new HttpHeaders(); | |
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); | |
URI uri = serverRunning.buildUri("/auth/oauth/authorize").queryParam("response_type", "code") | |
.queryParam("state", "mystateid").queryParam("client_id", "app") | |
.queryParam("redirect_uri", "http://anywhere").build(); | |
ResponseEntity<Void> result = serverRunning.getForResponse(uri.toString(), headers); | |
assertEquals(HttpStatus.FOUND, result.getStatusCode()); | |
String location = result.getHeaders().getLocation().toString(); | |
ResponseEntity<String> response = serverRunning.getForString(location, headers); | |
// should be directed to the login screen... | |
assertTrue(response.getBody().contains("auth/login.do")); | |
assertTrue(response.getBody().contains("username")); | |
assertTrue(response.getBody().contains("password")); | |
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); | |
formData.add("username", "marissa"); | |
formData.add("password", "koala"); | |
// response = serverRunning.postForString("/auth/login.do", formData, headers); | |
// TODO finish flow, + or use HTML content type | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dn: ou=groups,dc=springframework,dc=org | |
objectclass: top | |
objectclass: organizationalUnit | |
ou: groups | |
dn: ou=people,dc=springframework,dc=org | |
objectclass: top | |
objectclass: organizationalUnit | |
ou: people | |
dn: uid=marissa,ou=people,dc=springframework,dc=org | |
objectclass: top | |
objectclass: person | |
objectclass: organizationalPerson | |
objectclass: inetOrgPerson | |
cn: Marissa | |
sn: Marissa | |
uid: marissa | |
userPassword: koala | |
dn: uid=paul,ou=people,dc=springframework,dc=org | |
objectclass: top | |
objectclass: person | |
objectclass: organizationalPerson | |
objectclass: inetOrgPerson | |
cn: Paul | |
sn: Paul | |
uid: paul | |
userPassword: emu | |
dn: cn=user,ou=groups,dc=springframework,dc=org | |
objectclass: top | |
objectclass: groupOfNames | |
cn: user | |
member: uid=marissa,ou=people,dc=springframework,dc=org | |
member: uid=paul,ou=people,dc=springframework,dc=org |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="ISO-8859-1"?> | |
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> | |
<filter> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | |
<init-param> | |
<param-name>contextAttribute</param-name> | |
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value> | |
</init-param> | |
</filter> | |
<filter-mapping> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<url-pattern>/*</url-pattern> | |
</filter-mapping> | |
<servlet> | |
<servlet-name>spring</servlet-name> | |
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | |
<load-on-startup>1</load-on-startup> | |
</servlet> | |
<servlet-mapping> | |
<servlet-name>spring</servlet-name> | |
<url-pattern>/</url-pattern> | |
</servlet-mapping> | |
</web-app> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="ISO-8859-1"?> | |
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> | |
<filter> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | |
<init-param> | |
<param-name>contextAttribute</param-name> | |
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value> | |
</init-param> | |
</filter> | |
<filter-mapping> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<url-pattern>/*</url-pattern> | |
</filter-mapping> | |
<servlet> | |
<servlet-name>spring</servlet-name> | |
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | |
<load-on-startup>1</load-on-startup> | |
</servlet> | |
<servlet-mapping> | |
<servlet-name>spring</servlet-name> | |
<url-pattern>/</url-pattern> | |
</servlet-mapping> | |
</web-app> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="ISO-8859-1"?> | |
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> | |
<filter> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | |
<init-param> | |
<param-name>contextAttribute</param-name> | |
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value> | |
</init-param> | |
</filter> | |
<filter-mapping> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<url-pattern>/*</url-pattern> | |
</filter-mapping> | |
<servlet> | |
<servlet-name>spring</servlet-name> | |
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | |
<load-on-startup>1</load-on-startup> | |
</servlet> | |
<servlet-mapping> | |
<servlet-name>spring</servlet-name> | |
<url-pattern>/</url-pattern> | |
</servlet-mapping> | |
</web-app> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="ISO-8859-1"?> | |
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> | |
<filter> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | |
<init-param> | |
<param-name>contextAttribute</param-name> | |
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value> | |
</init-param> | |
</filter> | |
<filter-mapping> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<url-pattern>/*</url-pattern> | |
</filter-mapping> | |
<servlet> | |
<servlet-name>spring</servlet-name> | |
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | |
<load-on-startup>1</load-on-startup> | |
</servlet> | |
<servlet-mapping> | |
<servlet-name>spring</servlet-name> | |
<url-pattern>/</url-pattern> | |
</servlet-mapping> | |
</web-app> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment