You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by bd...@apache.org on 2016/11/08 14:50:06 UTC
shiro git commit: Initial commit for openid4j support
Repository: shiro
Updated Branches:
refs/heads/openid4j [created] aef52690d
Initial commit for openid4j support
This reverts commit 3a23929a8d3d2f13ebe3365ca66f94d51b5bdbe6.
Project: http://git-wip-us.apache.org/repos/asf/shiro/repo
Commit: http://git-wip-us.apache.org/repos/asf/shiro/commit/aef52690
Tree: http://git-wip-us.apache.org/repos/asf/shiro/tree/aef52690
Diff: http://git-wip-us.apache.org/repos/asf/shiro/diff/aef52690
Branch: refs/heads/openid4j
Commit: aef52690df6105cb260207fb622094fdc8c161ca
Parents: e8ba5cb
Author: Brian Demers <bd...@apache.org>
Authored: Tue Nov 8 09:48:39 2016 -0500
Committer: Brian Demers <bd...@apache.org>
Committed: Tue Nov 8 09:49:44 2016 -0500
----------------------------------------------------------------------
pom.xml | 10 ++
support/openid4j/pom.xml | 91 ++++++++++
.../shiro/openid4j/ConstructedRequest.java | 33 ++++
.../shiro/openid4j/DefaultOpenIdService.java | 148 +++++++++++++++++
.../shiro/openid4j/DiscoveryException.java | 29 ++++
.../shiro/openid4j/DiscoveryIdResolver.java | 27 +++
.../shiro/openid4j/MessageExtensionFactory.java | 31 ++++
.../apache/shiro/openid4j/OpenIdException.java | 31 ++++
.../apache/shiro/openid4j/OpenIdService.java | 29 ++++
.../openid4j/SimpleConstructedRequest.java | 44 +++++
.../shiro/openid4j/ax/AttributeDefinition.java | 34 ++++
.../shiro/openid4j/ax/AttributeProperty.java | 118 +++++++++++++
.../shiro/openid4j/ax/FetchRequestFactory.java | 164 +++++++++++++++++++
.../openid4j/ax/SimpleAttributeDefinition.java | 74 +++++++++
.../shiro/openid4j/realm/RelyingPartyRealm.java | 57 +++++++
.../groovy/AttributeTypeScreenScraper.groovy | 100 +++++++++++
.../openid4j/ax/FetchRequestFactoryTest.groovy | 47 ++++++
.../src/test/resources/log4j.properties | 37 +++++
support/pom.xml | 1 +
19 files changed, 1105 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8fe6095..be27f19 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,7 @@
<hsqldb.version>1.8.0.7</hsqldb.version>
<jdk.version>1.6</jdk.version>
<jetty.version>9.3.0.M1</jetty.version>
+ <openid4j.version>0.9.5</openid4j.version>
<!-- Don't change this version without also changing the shiro-quartz and shiro-features
modules' OSGi metadata: -->
<quartz.version>1.6.1</quartz.version>
@@ -736,6 +737,15 @@
</dependency>
<dependency>
+ <groupId>org.openid4java</groupId>
+ <artifactId>openid4java-consumer</artifactId>
+ <!--artifactId>openid4java-server</artifactId-->
+ <!--artifactId>openid4java-infocard</artifactId-->
+ <!--artifactId>openid4java-xri</artifactId-->
+ <!--artifactId>openid4java</artifactId-->
+ <version>${openid4j.version}</version>
+ </dependency>
+ <dependency>
<!-- Used for Atlassian Crowd Realm - not required for the framework: -->
<groupId>com.atlassian.crowd</groupId>
<artifactId>crowd-integration-client</artifactId>
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/pom.xml
----------------------------------------------------------------------
diff --git a/support/openid4j/pom.xml b/support/openid4j/pom.xml
new file mode 100644
index 0000000..44c7c01
--- /dev/null
+++ b/support/openid4j/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+<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">
+
+ <parent>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-root</artifactId>
+ <version>2.alpha.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>shiro-openid4j</artifactId>
+ <name>Apache Shiro :: Support :: OpenId4J</name>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openid4java</groupId>
+ <artifactId>openid4java-consumer</artifactId>
+ </dependency>
+
+ <!-- Test dependencies -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.apache.shiro.openid4j</Bundle-SymbolicName>
+ <Export-Package>org.apache.shiro.openid4j*;version=${project.version}</Export-Package>
+ <Import-Package>
+ org.apache.shiro*;version="${shiro.osgi.importRange}",
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/ConstructedRequest.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/ConstructedRequest.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ConstructedRequest.java
new file mode 100644
index 0000000..4f3b7f8
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ConstructedRequest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.message.AuthRequest;
+
+/**
+ *
+ * @since 1.2
+ */
+public interface ConstructedRequest {
+
+ DiscoveryInformation getDiscoveryInfo();
+
+ AuthRequest getAuthenticationRequest();
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/DefaultOpenIdService.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/DefaultOpenIdService.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/DefaultOpenIdService.java
new file mode 100644
index 0000000..067e3e4
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/DefaultOpenIdService.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+import org.apache.shiro.util.CollectionUtils;
+import org.apache.shiro.util.StringUtils;
+import org.openid4java.OpenIDException;
+import org.openid4java.consumer.ConsumerException;
+import org.openid4java.consumer.ConsumerManager;
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.message.AuthRequest;
+import org.openid4java.message.MessageException;
+import org.openid4java.message.MessageExtension;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Default implementation of the {@link OpenIdService} interface.
+ *
+ * @since 1.2
+ */
+public class DefaultOpenIdService implements OpenIdService {
+
+ private ConsumerManager consumerManager;
+ private DiscoveryIdResolver discoveryIdResolver;
+ private Collection<MessageExtensionFactory> messageExtensionFactories;
+
+
+ public DefaultOpenIdService() {
+ try {
+ //The ConsumerManager class is frustrating - at the time of this implementation
+ //(2011.02.18), this constructor's source code never throws a ConsumerException - probably left in
+ //place to be backwards compatible with a previous release that did throw that exception.
+ //Another failing of checked exceptions and not programming to interfaces...
+ this.consumerManager = new ConsumerManager();
+ } catch (ConsumerException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public ConsumerManager getConsumerManager() {
+ return consumerManager;
+ }
+
+ public void setConsumerManager(ConsumerManager consumerManager) {
+ this.consumerManager = consumerManager;
+ }
+
+ public DiscoveryIdResolver getDiscoveryIdResolver() {
+ return discoveryIdResolver;
+ }
+
+ public void setDiscoveryIdResolver(DiscoveryIdResolver discoveryIdResolver) {
+ this.discoveryIdResolver = discoveryIdResolver;
+ }
+
+ public Collection<MessageExtensionFactory> getMessageExtensionFactories() {
+ return messageExtensionFactories;
+ }
+
+ public void setMessageExtensionFactories(Collection<MessageExtensionFactory> messageExtensionFactories) {
+ this.messageExtensionFactories = messageExtensionFactories;
+ }
+
+ public ConstructedRequest constructRequest(String providerId, String responseUrl) throws OpenIdException {
+ String discoveryId = getDiscoveryId(providerId);
+
+ DiscoveryInformation discoveryInfo = getDiscoveryInfo(discoveryId, providerId);
+
+ AuthRequest request = createRequest(discoveryInfo, responseUrl);
+
+ addExtensions(request, discoveryInfo, providerId, discoveryId);
+
+ return createConstructedRequest(request, discoveryInfo, providerId, discoveryId);
+ }
+
+ private void addExtensions(AuthRequest request, DiscoveryInformation info, String serviceId, String discoveryId) {
+ if (!CollectionUtils.isEmpty(this.messageExtensionFactories)) {
+ for( MessageExtensionFactory factory : this.messageExtensionFactories ) {
+ MessageExtension extension = factory.createMessageExtension(request, info, serviceId, discoveryId);
+ if (extension != null) {
+ try {
+ request.addExtension(extension);
+ } catch (MessageException e) {
+ String msg = "Unable to add message extension.";
+ throw new OpenIdException(msg, e);
+ }
+ }
+ }
+ }
+ }
+
+ protected String getDiscoveryId(String providerId) {
+ String discoveryId = providerId;
+ if (this.discoveryIdResolver != null) {
+ discoveryId = this.discoveryIdResolver.resolveDiscoveryId(providerId);
+ if (!StringUtils.hasText(discoveryId)) {
+ throw new IllegalStateException("DiscoveryIdResolver returned a null, blank or empty string.");
+ }
+ } else {
+ if (!StringUtils.hasText(providerId)) {
+ throw new IllegalArgumentException("providerId argument cannot be null, empty or blank.");
+ }
+ }
+ return discoveryId;
+ }
+
+ protected DiscoveryInformation getDiscoveryInfo(String discoveryId, String providerId) throws DiscoveryException {
+ try {
+ List discoveries = consumerManager.discover(discoveryId);
+ return consumerManager.associate(discoveries);
+ } catch (OpenIDException e) {
+ String msg = "Unable to discover OpenId Provider based on resolved discoveryId '" + discoveryId + "' " +
+ "(specified providerId '" + providerId + "')";
+ throw new DiscoveryException(msg, e);
+ }
+ }
+
+ protected AuthRequest createRequest(DiscoveryInformation info, String responseUrl) throws OpenIdException {
+ try {
+ return consumerManager.authenticate(info, responseUrl);
+ } catch (OpenIDException e) {
+ throw new OpenIdException("Unable to create AuthRequest.", e);
+ }
+ }
+
+ protected ConstructedRequest createConstructedRequest(AuthRequest request, DiscoveryInformation info,
+ String providerId, String discoveryId) {
+ return new SimpleConstructedRequest(request, info);
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryException.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryException.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryException.java
new file mode 100644
index 0000000..c524c79
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryException.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+/**
+ * @since 1.2
+ */
+public class DiscoveryException extends OpenIdException {
+
+ public DiscoveryException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryIdResolver.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryIdResolver.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryIdResolver.java
new file mode 100644
index 0000000..dc0fa63
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/DiscoveryIdResolver.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+/**
+ * @since 1.2
+ */
+public interface DiscoveryIdResolver {
+
+ String resolveDiscoveryId(String id);
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/MessageExtensionFactory.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/MessageExtensionFactory.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/MessageExtensionFactory.java
new file mode 100644
index 0000000..fc82298
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/MessageExtensionFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.message.AuthRequest;
+import org.openid4java.message.MessageExtension;
+
+/**
+ * @since 1.2
+ */
+public interface MessageExtensionFactory<T extends MessageExtension> {
+
+ T createMessageExtension(AuthRequest request, DiscoveryInformation info, String serviceId, String discoveryId);
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdException.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdException.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdException.java
new file mode 100644
index 0000000..8c0d704
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdException.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+import org.apache.shiro.authc.AuthenticationException;
+
+/**
+ * @since 1.2
+ */
+public class OpenIdException extends AuthenticationException {
+
+ public OpenIdException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdService.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdService.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdService.java
new file mode 100644
index 0000000..6d7b5ac
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/OpenIdService.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+/**
+ * @since 1.2
+ */
+public interface OpenIdService {
+
+ ConstructedRequest constructRequest(String providerId, String responseUrl) throws OpenIdException;
+
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/SimpleConstructedRequest.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/SimpleConstructedRequest.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/SimpleConstructedRequest.java
new file mode 100644
index 0000000..d2fda21
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/SimpleConstructedRequest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j;
+
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.message.AuthRequest;
+
+/**
+ * @since 1.2
+ */
+public class SimpleConstructedRequest implements ConstructedRequest {
+
+ private final DiscoveryInformation discoveryInfo;
+ private final AuthRequest authenticationRequest;
+
+ public SimpleConstructedRequest(AuthRequest authRequest, DiscoveryInformation info) {
+ this.authenticationRequest = authRequest;
+ this.discoveryInfo = info;
+ }
+
+ public DiscoveryInformation getDiscoveryInfo() {
+ return discoveryInfo;
+ }
+
+ public AuthRequest getAuthenticationRequest() {
+ return authenticationRequest;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeDefinition.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeDefinition.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeDefinition.java
new file mode 100644
index 0000000..787c56e
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeDefinition.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j.ax;
+
+/**
+ * @since 1.2
+ */
+public interface AttributeDefinition {
+
+ String getName();
+
+ String getUri();
+
+ boolean isRequired();
+
+ int getCount();
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeProperty.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeProperty.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeProperty.java
new file mode 100644
index 0000000..8f7714b
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/AttributeProperty.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j.ax;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An Enum representing all de-facto standard <a href="http://www.axschema.org/types/">
+ * Attribute Exchange Types</a>.
+ *
+ * @since 1.2
+ */
+public enum AttributeProperty {
+
+ Username("http://axschema.org/namePerson/friendly", "Alias/Username"),
+ FullName("http://axschema.org/namePerson", "Full name"),
+ NamePrefix("http://axschema.org/namePerson/prefix", "Name prefix"),
+ FirstName("http://axschema.org/namePerson/first", "First name"),
+ LastName("http://axschema.org/namePerson/last", "Last name"),
+ MiddleName("http://axschema.org/namePerson/middle", "Middle name"),
+ NameSuffix("http://axschema.org/namePerson/suffix", "Name suffix"),
+ CompanyName("http://axschema.org/company/name", "Company name"),
+ JobTitle("http://axschema.org/company/title", "Job title"),
+ BirthDate("http://axschema.org/birthDate", "Birth date"),
+ BirthYear("http://axschema.org/birthDate/birthYear", "Birth year"),
+ BirthMonth("http://axschema.org/birthDate/birthMonth", "Birth month"),
+ BirthDay("http://axschema.org/birthDate/birthday", "Birth day"),
+ PhonePreferred("http://axschema.org/contact/phone/default", "Phone (preferred)"),
+ PhoneHome("http://axschema.org/contact/phone/home", "Phone (home)"),
+ PhoneWork("http://axschema.org/contact/phone/business", "Phone (work)"),
+ PhoneMobile("http://axschema.org/contact/phone/cell", "Phone (mobile)"),
+ PhoneFax("http://axschema.org/contact/phone/fax", "Phone (fax)"),
+ Address("http://axschema.org/contact/postalAddress/home", "Address"),
+ Address2("http://axschema.org/contact/postalAddressAdditional/home", "Address 2"),
+ City("http://axschema.org/contact/city/home", "City"),
+ State("http://axschema.org/contact/state/home", "State/Province"),
+ Country("http://axschema.org/contact/country/home", "Country"),
+ PostalCode("http://axschema.org/contact/postalCode/home", "Postal code"),
+ BusinessAddress("http://axschema.org/contact/postalAddress/business", "Address"),
+ BusinessAddress2("http://axschema.org/contact/postalAddressAdditional/business", "Address 2"),
+ BusinessCity("http://axschema.org/contact/city/business", "City"),
+ BusinessState("http://axschema.org/contact/state/business", "State/Province"),
+ BusinessCountry("http://axschema.org/contact/country/business", "Country"),
+ BusinessPostalCode("http://axschema.org/contact/postalCode/business", "Postal code"),
+ Email("http://axschema.org/contact/email", "Email"),
+ AOLIM("http://axschema.org/contact/IM/AIM", "AOL IM"),
+ ICQIM("http://axschema.org/contact/IM/ICQ", "ICQ IM"),
+ MSNIM("http://axschema.org/contact/IM/MSN", "MSN IM"),
+ YahooIM("http://axschema.org/contact/IM/Yahoo", "Yahoo! IM"),
+ JabberIM("http://axschema.org/contact/IM/Jabber", "Jabber IM"),
+ SkypeIM("http://axschema.org/contact/IM/Skype", "Skype IM"),
+ WebPage("http://axschema.org/contact/web/default", "Web page"),
+ Blog("http://axschema.org/contact/web/blog", "Blog"),
+ LinkedInURL("http://axschema.org/contact/web/Linkedin", "LinkedIn URL"),
+ AmazonURL("http://axschema.org/contact/web/Amazon", "Amazon URL"),
+ FlickrURL("http://axschema.org/contact/web/Flickr", "Flickr URL"),
+ DeliciousURL("http://axschema.org/contact/web/Delicious", "del.icio.us URL"),
+ SpokenName("http://axschema.org/media/spokenname", "Spoken name"),
+ AudioGreeting("http://axschema.org/media/greeting/audio", "Audio greeting"),
+ VideoGreeting("http://axschema.org/media/greeting/video", "Video greeting"),
+ Image("http://axschema.org/media/image/default", "Image"),
+ SquareImage("http://axschema.org/media/image/aspect11", "Square image"),
+ Aspect43Image("http://axschema.org/media/image/aspect43", "4:3 aspect image"),
+ Aspect34Image("http://axschema.org/media/image/aspect34", "3:4 aspect image"),
+ FaviconImage("http://axschema.org/media/image/favicon", "Favicon image"),
+ Gender("http://axschema.org/person/gender", "Gender"),
+ Language("http://axschema.org/pref/language", "Language"),
+ TimeZone("http://axschema.org/pref/timezone", "Time zone");
+
+ private static final Map<String, AttributeProperty> caseInsensitiveNameMap;
+
+ static {
+ caseInsensitiveNameMap = new HashMap<String, AttributeProperty>();
+ for (AttributeProperty prop : values()) {
+ caseInsensitiveNameMap.put(prop.name().toLowerCase(), prop);
+ }
+ }
+
+ private final String label;
+ private final String uri;
+
+ private AttributeProperty(String uri, String label) {
+ this.uri = uri;
+ this.label = label;
+ }
+
+ public static AttributeProperty fromName(String caseInsensitiveName) {
+ if (caseInsensitiveName == null) {
+ return null;
+ }
+ return caseInsensitiveNameMap.get(caseInsensitiveName.toLowerCase());
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/FetchRequestFactory.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/FetchRequestFactory.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/FetchRequestFactory.java
new file mode 100644
index 0000000..499119a
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/FetchRequestFactory.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j.ax;
+
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.openid4j.MessageExtensionFactory;
+import org.apache.shiro.openid4j.OpenIdException;
+import org.apache.shiro.util.StringUtils;
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.message.AuthRequest;
+import org.openid4java.message.MessageException;
+import org.openid4java.message.ax.FetchRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @since 1.2
+ */
+public class FetchRequestFactory implements MessageExtensionFactory<FetchRequest> {
+
+ private static final Logger log = LoggerFactory.getLogger(FetchRequestFactory.class);
+
+ private Map<String, String> providerAttributes;
+
+ public FetchRequestFactory() {
+ this.providerAttributes = new HashMap<String,String>();
+ }
+
+ public Map<String, String> getProviderAttributes() {
+ return providerAttributes;
+ }
+
+ public void setProviderAttributes(Map<String, String> providerAttributes) {
+ this.providerAttributes = providerAttributes;
+ }
+
+ public FetchRequest createMessageExtension(AuthRequest request, DiscoveryInformation info, String serviceId, String discoveryId) {
+
+ String definition = providerAttributes.get(serviceId);
+ if (definition == null) {
+ definition = providerAttributes.get(discoveryId);
+ }
+ if (definition == null) {
+ return null;
+ }
+
+ String[] attributes = StringUtils.split(definition);
+ if (attributes == null || attributes.length == 0) {
+ return null;
+ }
+
+ FetchRequest fetch = FetchRequest.createFetchRequest();
+
+ //parse the definition by tokenizing it to get the resulting attribute-specific config
+ //
+ //e.g. for a value of
+ //
+ // "email, firstName[required=true], lastName"
+ //
+ // the resulting token array would equal
+ //
+ // { "email", "firstName[required=true]", "lastName" }
+ //
+ for (String attribute : attributes) {
+ //strip the name and extract any attribute-specific config between brackets [ ]
+ String[] nameAndConfig = attribute.split("\\[", 2);
+ String name = nameAndConfig[0];
+ String config = null;
+
+ if (nameAndConfig.length == 2) {
+ config = nameAndConfig[1];
+ //if there was an open bracket, there was a close bracket, so strip it too:
+ config = config.substring(0, config.length() - 1);
+ }
+
+ AttributeDefinition ad = toDefinition(name, config);
+
+ try {
+ fetch.addAttribute(ad.getName(), ad.getUri(), ad.isRequired(), ad.getCount());
+ } catch (MessageException e) {
+ throw new OpenIdException("Unable to correctly add 'fetch' attribute.", e);
+ }
+ }
+
+ return fetch;
+ }
+
+ protected AttributeDefinition toDefinition(String name, String config) {
+
+ AttributeProperty prop = AttributeProperty.fromName(name);
+ if (prop == null) {
+ throw new ConfigurationException("Unable to locate a standard OpenId Attribute property for name '" +
+ name + "'. Please ensure this name matches one of the constants in the " +
+ AttributeProperty.class.getName() + " enum (name matching is case insensitive).");
+ }
+
+ String uri = prop.getUri();
+ boolean required = false;
+ int count = 0;
+
+
+ if (config != null) {
+ String[] configPairs = StringUtils.split(config);
+ for (String pair : configPairs) {
+ String nameValue[] = pair.split("\\=", 2);
+ if (nameValue.length != 2) {
+ throw new ConfigurationException("OpenId attribute properties with configuration must be " +
+ "comma-delimited name/value pairs. Each name/value pair must be separated by the " +
+ "equals sign, e.g. nameProp[name1=value1, name2=value2, ...]. The string that " +
+ "caused this error was '" + pair + "'.");
+ }
+ String pairName = nameValue[0];
+ String pairValue = nameValue[1];
+
+ if ("uri".equalsIgnoreCase(pairName)) {
+ uri = pairValue;
+ } else if ("required".equalsIgnoreCase(pairName)) {
+ required = Boolean.valueOf(pairValue);
+ } else if ("count".equalsIgnoreCase(pairName)) {
+ try {
+ count = Integer.parseInt(pairValue);
+ } catch (NumberFormatException e) {
+ String msg = "Unable to correctly parse 'count' value '" + pairValue + "' for OpenId " +
+ "attribute '" + name + "'";
+ throw new ConfigurationException(msg, e);
+ }
+ if (count < 0) {
+ count = 0;
+ }
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn("Unrecognized configuration name/value pair for OpenId attribute '{}': {}={}",
+ new Object[]{name, pairName, pairValue});
+ }
+
+ }
+ }
+ }
+
+
+ return new SimpleAttributeDefinition(prop.name(), uri, required, count);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/SimpleAttributeDefinition.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/SimpleAttributeDefinition.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/SimpleAttributeDefinition.java
new file mode 100644
index 0000000..bd7de70
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/ax/SimpleAttributeDefinition.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j.ax;
+
+import org.apache.shiro.openid4j.ax.AttributeDefinition;
+
+/**
+ * @since 1.2
+ */
+public class SimpleAttributeDefinition implements AttributeDefinition {
+
+ private String name;
+ private String uri;
+ private boolean required;
+ private int count;
+
+ public SimpleAttributeDefinition() {
+ }
+
+ public SimpleAttributeDefinition(String name, String uri, boolean required, int count) {
+ this.name = name;
+ this.uri = uri;
+ this.required = required;
+ this.count = count;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ public void setRequired(boolean required) {
+ this.required = required;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/main/java/org/apache/shiro/openid4j/realm/RelyingPartyRealm.java
----------------------------------------------------------------------
diff --git a/support/openid4j/src/main/java/org/apache/shiro/openid4j/realm/RelyingPartyRealm.java b/support/openid4j/src/main/java/org/apache/shiro/openid4j/realm/RelyingPartyRealm.java
new file mode 100644
index 0000000..8f65006
--- /dev/null
+++ b/support/openid4j/src/main/java/org/apache/shiro/openid4j/realm/RelyingPartyRealm.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j.realm;
+
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.openid4j.OpenIdService;
+import org.apache.shiro.realm.AuthenticatingRealm;
+
+/**
+ * A {@code Realm} implementation that performs OpenID authentication by acting as the "Relying Party"
+ * (client) to an OpenId Provider (server).
+ *
+ * @since 1.2
+ */
+public class RelyingPartyRealm extends AuthenticatingRealm {
+
+ private OpenIdService openIdService;
+
+ public RelyingPartyRealm() {
+
+ }
+
+ public OpenIdService getOpenIdService() {
+ return openIdService;
+ }
+
+ public void setOpenIdService(OpenIdService openIdService) {
+ this.openIdService = openIdService;
+ }
+
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+
+ //TODO
+
+ return null;
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/test/groovy/AttributeTypeScreenScraper.groovy
----------------------------------------------------------------------
diff --git a/support/openid4j/src/test/groovy/AttributeTypeScreenScraper.groovy b/support/openid4j/src/test/groovy/AttributeTypeScreenScraper.groovy
new file mode 100644
index 0000000..d11a8bc
--- /dev/null
+++ b/support/openid4j/src/test/groovy/AttributeTypeScreenScraper.groovy
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * @since 1.2
+ */
+class AttributeTypeScreenScraper extends GroovyTestCase {
+
+ void testNothing() {}
+
+ //used to generate constants in the AttributeProperty class:
+ void doTestScrape() {
+
+ //file copied from the OpenId website:
+ def resource = "http://www.axschema.org/types/";
+
+ def properties = []
+ def property = [:]
+
+ boolean parsing = false;
+
+ resource.toURL().eachLine("UTF-8", { String line ->
+
+ line = line.trim()
+
+ if (line.equals("<table id=\"types\">")) {
+ parsing = true;
+ }
+ if (parsing && line.equals("</table>")) {
+ parsing = false
+ }
+ if (parsing) {
+ if (line.equals("<tr>") && property.size() == 3) {
+ properties << property
+ property = [:]
+ }
+ if (line.startsWith("<td") && line.endsWith("</a></td>")) {
+ int index = line.lastIndexOf("http://");
+ line = line.substring(index, line.length() - "</a></td>".length())
+ property.uri = line
+ } else if (line.startsWith("<td>") && line.endsWith("</td>") && !line.contains(" ")) {
+ line = line.substring(4, line.length() - 5)
+ property.label = line
+
+ String[] words = property.label.split(" ");
+ String varName = "";
+ for( String s : words ) {
+ s = s.replace("(", "")
+ s = s.replace(")", "")
+ s = s.replace(".", "")
+ int index = s.indexOf("/")
+ if (index > 0) {
+ s = s.substring(0, index)
+ }
+ varName += s.capitalize()
+ }
+
+ //special cases:
+ if (property.uri.endsWith("business")) {
+ varName = "Business" + varName;
+ }
+ if (varName == "Alias") {
+ varName = "Username"
+ }
+ if (varName == "Yahoo!IM") {
+ varName = "YahooIM"
+ }
+ if (varName == "4:3AspectImage") {
+ varName = "Aspect43Image"
+ }
+ if (varName == "3:4AspectImage") {
+ varName = "Aspect34Image"
+ }
+ property.name = varName;
+ }
+ }
+ });
+ for (def prop: properties) {
+ String d = "${prop.name}(\"${prop.uri}\", \"${prop.label}\"), ";
+ System.out.println(d);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/test/groovy/org/apache/shiro/openid4j/ax/FetchRequestFactoryTest.groovy
----------------------------------------------------------------------
diff --git a/support/openid4j/src/test/groovy/org/apache/shiro/openid4j/ax/FetchRequestFactoryTest.groovy b/support/openid4j/src/test/groovy/org/apache/shiro/openid4j/ax/FetchRequestFactoryTest.groovy
new file mode 100644
index 0000000..7d72fc4
--- /dev/null
+++ b/support/openid4j/src/test/groovy/org/apache/shiro/openid4j/ax/FetchRequestFactoryTest.groovy
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.shiro.openid4j.ax
+
+import org.openid4java.message.ax.FetchRequest
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: lhazlewood
+ * Date: 2/21/11
+ * Time: 10:04 PM
+ * To change this template use File | Settings | File Templates.
+ */
+class FetchRequestFactoryTest extends GroovyTestCase {
+
+ void testCreateWithProviderAttributes() {
+
+ FetchRequestFactory factory = new FetchRequestFactory();
+
+ factory.providerAttributes.google = "email[count=1], firstName[required=true], lastName"
+
+ FetchRequest request = factory.createMessageExtension(null, null, "google", null);
+
+ assertNotNull request
+ def list = request.getParameters();
+ System.out.println(list);
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/openid4j/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/support/openid4j/src/test/resources/log4j.properties b/support/openid4j/src/test/resources/log4j.properties
new file mode 100644
index 0000000..0d51520
--- /dev/null
+++ b/support/openid4j/src/test/resources/log4j.properties
@@ -0,0 +1,37 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+log4j.rootLogger=TRACE, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
+
+# Pattern to output: date priority [category] - message
+log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
+log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
+
+# Spring logging level is WARN
+log4j.logger.net.sf.ehcache=INFO
+
+# General Apache libraries is WARN
+log4j.logger.org.apache=WARN
+
+log4j.logger.org.apache.shiro=TRACE
+log4j.logger.org.apache.shiro.util.ThreadContext=WARN
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/aef52690/support/pom.xml
----------------------------------------------------------------------
diff --git a/support/pom.xml b/support/pom.xml
index 8886f02..fd7f801 100644
--- a/support/pom.xml
+++ b/support/pom.xml
@@ -38,6 +38,7 @@
<module>quartz</module>
<module>spring</module>
<module>guice</module>
+ <module>openid4j</module>
<module>features</module>
<module>cas</module>
<module>spring-boot</module>