Author: ivol37 at gmail.com Date: Thu Dec 2 09:40:25 2010 New Revision: 466
Log: [AMDATU-181] Initial drop in of separate oAuth api, client and server. The API exposes the net.oauth and Amdatu specific api, the oAuth client provides a simple oAuth client for resource owners and service consumers and the oAuth server provides an implementation of the three oAuth endpoints (request token, authorize token and access token) including a consumer registry. The registry is provided with a simple REST interface. This initial implementation implements three-legged oAuth. Added: trunk/amdatu-authentication/ trunk/amdatu-authentication/oauth-api/ trunk/amdatu-authentication/oauth-api/pom.xml trunk/amdatu-authentication/oauth-api/src/ trunk/amdatu-authentication/oauth-api/src/main/ trunk/amdatu-authentication/oauth-api/src/main/java/ trunk/amdatu-authentication/oauth-api/src/main/java/org/ trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/ trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/ trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/ trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/ trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthServiceConsumer.java trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthServiceProvider.java trunk/amdatu-authentication/oauth-client/ trunk/amdatu-authentication/oauth-client/pom.xml trunk/amdatu-authentication/oauth-client/src/ trunk/amdatu-authentication/oauth-client/src/main/ trunk/amdatu-authentication/oauth-client/src/main/java/ trunk/amdatu-authentication/oauth-client/src/main/java/org/ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthResourceOwnerClient.java trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthServiceConsumerClient.java trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/internal/ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/internal/OAuthClientBase.java trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/osgi/ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/osgi/Activator.java trunk/amdatu-authentication/oauth-server/ trunk/amdatu-authentication/oauth-server/pom.xml trunk/amdatu-authentication/oauth-server/src/ trunk/amdatu-authentication/oauth-server/src/main/ trunk/amdatu-authentication/oauth-server/src/main/java/ trunk/amdatu-authentication/oauth-server/src/main/java/org/ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/ConsumerAlreadyExistsException.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/ConsumerNotFoundException.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthAccessTokenServlet.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthAuthorizeTokenServlet.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthRequestTokenServlet.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthServiceConsumerRegistry.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthTokenProvider.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/osgi/ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/osgi/Activator.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthAccessTokenServletImpl.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthAuthorizeTokenServletImpl.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthRequestTokenServletImpl.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthResourceProviderImpl.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerBean.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerRegistryImpl.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerRegistryREST.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceProviderImpl.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServlet.java trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthTokenProviderImpl.java trunk/amdatu-authentication/oauth-server/src/main/resources/ trunk/amdatu-authentication/oauth-server/src/main/resources/jsp/ trunk/amdatu-authentication/oauth-server/src/main/resources/jsp/authorize.jsp trunk/amdatu-authentication/pom.xml Added: trunk/amdatu-authentication/oauth-api/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-api/pom.xml Thu Dec 2 09:40:25 2010 @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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.amdatu</groupId> + <artifactId>org.amdatu.authentication</artifactId> + <version>0.0.6-SNAPSHOT</version> + </parent> + <groupId>org.amdatu.authentication.oauth</groupId> + <artifactId>api</artifactId> + <packaging>bundle</packaging> + <name>Amdatu Authentication - oAuth API (net.oauth)</name> + <description>This bundle includes the net.oauth API</description> + + <dependencies> + <dependency> + <groupId>net.oauth.core</groupId> + <artifactId>oauth</artifactId> + <version>20100527</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>net.oauth.core</groupId> + <artifactId>oauth-provider</artifactId> + <version>20100527</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>net.oauth.core</groupId> + <artifactId>oauth-consumer</artifactId> + <version>20100527</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>net.oauth.core</groupId> + <artifactId>oauth-httpclient4</artifactId> + <version>20090913</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore-osgi</artifactId> + <version>4.0.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.0.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.16</version> + <scope>compile</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>org.amdatu.authentication.oauth.api</Bundle-SymbolicName> + <Embed-Transitive>true</Embed-Transitive> + <Embed-Dependency>*;scope=compile</Embed-Dependency> + <Import-Package>*;resolution:=optional</Import-Package> + <Export-Package>org.amdatu.authentication.oauth.api</Export-Package> + <_exportcontents> + net.oauth.* + </_exportcontents> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthServiceConsumer.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthServiceConsumer.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,58 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.api; + +/** + * This interface represents an oAuth service consumer. An oAuth service consumer is a service that invokes + * a service provider on behalf of another client. The service consumer communicates with the service provider + * using an access token. This access token is a request token that is authorized by the client first. + * The service consumer needs to identify itself with the service provider, such that the service provider + * can decide whether or not to grant access to this service consumer. This identification is based on the + * consumer key and secret. + * The callback URL is the URL to which the client is redirected to authorize a request token received earlier + * in the process and to exchange it for an access token. + * @author ivol + * + */ +public interface OAuthServiceConsumer { + /** + * Returns a descriptive name of this consumer. The name is used on the authorization page on which + * the user must allow this consumer to access its protected resource. + * @return name of this consumer. + */ + String getName(); + + /** + * Returns the consumer key. The consumer key is used by a consumer to identify itself to the + * service provider. + * @return + */ + String getConsumerKey(); + + /** + * Returns the consumer secret. The consumer secret is used by the Consumer to establish + * ownership of the Consumer Key. + * @return + */ + String getConsumerSecret(); + + /** + * Returns the URL to which users should be redirected after a request token has been authorized by this user. + * @return The URL to which a user will be redirected after a request token has been authorized. + */ + String getCallbackUrl(); +} Added: trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthServiceProvider.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthServiceProvider.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,42 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.api; + +/** + * This class represents an oAuth service provider. An oAuth service provider provides the three endpoints of + * an oAuth server; request token, authorize token and access token. + * @author ivol + */ +public interface OAuthServiceProvider { + /** + * Returns the URL of the oAuth server endpoint that generates the request tokens. + * @return The URL of the request token endpoint. + */ + String getRequestTokenURL(); + + /** + * Returns the URL of the oAuth server endpoint that authorizes request tokens. + * @return The URL of the authorize token endpoint. + */ + String getAuthorizeTokenURL(); + + /** + * Returns the URL of the oAuth server endpoint that exchanges request tokens for access tokens. + * @return The URL of the access token endpoint. + */ + String getAccessTokenURL(); +} Added: trunk/amdatu-authentication/oauth-client/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-client/pom.xml Thu Dec 2 09:40:25 2010 @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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.amdatu</groupId> + <artifactId>org.amdatu.authentication</artifactId> + <version>0.0.6-SNAPSHOT</version> + </parent> + <groupId>org.amdatu.authentication.oauth</groupId> + <artifactId>client</artifactId> + <packaging>bundle</packaging> + <name>Amdatu Authentication - oAuth client</name> + <description>This bundle includes an API for oAuth service consumers</description> + + <dependencies> + <dependency> + <groupId>org.amdatu.web</groupId> + <artifactId>httpcontext</artifactId> + <version>${platform.version}</version> + <scope>provided</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.authentication.oauth</groupId> + <artifactId>api</artifactId> + <version>${platform.version}</version> + <scope>provided</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.4</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-httpclient</groupId> + <artifactId>commons-httpclient</artifactId> + <version>3.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.16</version> + <scope>compile</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-Activator>org.amdatu.authentication.oauth.client.osgi.Activator</Bundle-Activator> + <Bundle-SymbolicName>org.amdatu.authentication.oauth.client</Bundle-SymbolicName> + <Export-Package>org.amdatu.authentication.oauth.client</Export-Package> + <Embed-Dependency>*;scope=compile</Embed-Dependency> + <Import-Package>*;resolution:=optional</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthResourceOwnerClient.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthResourceOwnerClient.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,93 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.client; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; + +import net.oauth.OAuthAccessor; +import net.oauth.OAuthException; +import net.oauth.OAuthMessage; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.authentication.oauth.api.OAuthServiceProvider; +import org.amdatu.authentication.oauth.client.internal.OAuthClientBase; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.PostMethod; + +public class OAuthResourceOwnerClient extends OAuthClientBase { + /** + * Create a new oAuth consumer client for the specified service consumer and service provider. + * + * @param provider The oAuth service provider + * @param consumer The oAuth service consumer + */ + public OAuthResourceOwnerClient(OAuthServiceProvider provider, OAuthServiceConsumer consumer) { + super(provider, consumer); + } + + /** + * Authorizes a request token with the specified userId without user interaction. + * @param accessor + * @param userId + * @return + * @throws IOException + * @throws URISyntaxException + * @throws OAuthException + * @return The callback url, if the service consumer provided it + */ + public String authorizeToken(OAuthAccessor accessor, String userId) throws IOException, URISyntaxException, OAuthException { + Map<String, String> paramProps = new HashMap<String, String>(); + paramProps.put("oauth_token", accessor.requestToken); + OAuthMessage response = sendRequest(accessor, paramProps, getProvider().getAuthorizeTokenURL()); + + // Now the result is an authorization page containing an HTML form we are supposed to submit + // First read the token and callback from this form + String sResponseBody = response.readBodyAsString(); + String tokenStart = "<input type=\"hidden\" name=\"oauth_token\" value=\""; + String token = sResponseBody.substring(sResponseBody.indexOf(tokenStart) + tokenStart.length()); + token = token.substring(0, token.indexOf("\"")); + + String callbackStart = "<input type=\"hidden\" name=\"oauth_callback\" value=\""; + String callback = sResponseBody.substring(sResponseBody.indexOf(callbackStart) + callbackStart.length()); + callback = callback.substring(0, callback.indexOf("\"")); + + // Now build the post request + HttpClient httpClient = new HttpClient(); + NameValuePair[] data = { + new NameValuePair("userId", userId), + new NameValuePair("oauth_token", token), + new NameValuePair("oauth_callback", callback) + }; + PostMethod postMethod = new PostMethod(getProvider().getAuthorizeTokenURL()); + postMethod.setRequestBody(data); + int status = httpClient.executeMethod(postMethod); + if (status == HttpStatus.SC_OK) { + // Status 200 means authorize token went OK, but service consumer did not specify a callback URL + return null; + } else if (status == HttpStatus.SC_MOVED_TEMPORARILY) { + // Status 302 means that we are being redirected to the callback url provided by the service consumer + return postMethod.getResponseHeader("Location").getValue(); + } else { + throw new OAuthException("Authorize token form returned " + status); + } + } +} Added: trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthServiceConsumerClient.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthServiceConsumerClient.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,105 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.client; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthException; +import net.oauth.OAuthMessage; +import net.oauth.client.httpclient4.HttpClient4; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.authentication.oauth.api.OAuthServiceProvider; +import org.amdatu.authentication.oauth.client.internal.OAuthClientBase; + +/** + * This class provides an oAuth client API to be used by Service consumers. It can be used by service consumers + * to invoke a remote oAuth server and retrieve request and access tokens. Note that it does not provide an API for + * authorizing tokens, since that is not up to the service consumer but up to the resource owner + * (see OAuthResourceOwnerClient for that). + * + * @author ivol + */ +public class OAuthServiceConsumerClient extends OAuthClientBase { + /** + * Create a new oAuth consumer client for the specified service consumer and service provider. + * + * @param provider The oAuth service provider + * @param consumer The oAuth service consumer + */ + public OAuthServiceConsumerClient(OAuthServiceProvider provider, OAuthServiceConsumer consumer) { + super(provider, consumer); + } + + /** + * Generates a request token and returns an OAuthAccessor which contains the generated token. To create a + * request token + * + * @param consumerKey The key that identifies the service consumer + * @param consumerSecret The secret that belongs to the consumer key + * @param callbackUrl The URL + * @return + * @throws IOException + * @throws OAuthException + * @throws URISyntaxException + */ + public OAuthAccessor generateRequestToken() throws IOException, OAuthException, URISyntaxException { + OAuthAccessor accessor = createAccessor(); + net.oauth.client.OAuthClient client = new net.oauth.client.OAuthClient(new HttpClient4()); + client.getRequestToken(accessor); + return accessor; + } + + /** + * Exchanges the request token for an access token. + * + * @param accessor + * @return + * @throws IOException + * @throws URISyntaxException + * @throws OAuthException + */ + public OAuthMessage getAccessToken(OAuthAccessor accessor ) throws IOException, URISyntaxException, OAuthException { + Map<String, String> paramProps = new HashMap<String, String>(); + paramProps.put("oauth_token", accessor.requestToken); + OAuthMessage response = sendRequest(accessor, paramProps, getProvider().getAccessTokenURL()); + return response; + } + + public OAuthMessage accessResource(OAuthAccessor accessor, String url) throws IOException, URISyntaxException, OAuthException { + Map<String, String> paramProps = new HashMap<String, String>(); + paramProps.put("oauth_token", accessor.accessToken); + return sendRequest(accessor, paramProps, url); + } + + public String toString(OAuthAccessor accessor) { + String result = ""; + result += OAuth.OAUTH_TOKEN + "=" + accessor.getProperty(OAuth.OAUTH_TOKEN) + " "; + result += OAuth.OAUTH_CONSUMER_KEY + "=" + accessor.getProperty(OAuth.OAUTH_CONSUMER_KEY) + " "; + result += OAuth.OAUTH_SIGNATURE_METHOD + "=" + accessor.getProperty(OAuth.OAUTH_SIGNATURE_METHOD) + " "; + result += OAuth.OAUTH_TIMESTAMP + "=" + accessor.getProperty(OAuth.OAUTH_TIMESTAMP) + " "; + result += OAuth.OAUTH_NONCE + "=" + accessor.getProperty(OAuth.OAUTH_NONCE) + " "; + result += OAuth.OAUTH_VERSION + "=" + accessor.getProperty(OAuth.OAUTH_VERSION); + return result; + } +} Added: trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/internal/OAuthClientBase.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/internal/OAuthClientBase.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,79 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.client.internal; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthConsumer; +import net.oauth.OAuthException; +import net.oauth.OAuthMessage; +import net.oauth.client.httpclient4.HttpClient4; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.authentication.oauth.api.OAuthServiceProvider; + +public class OAuthClientBase { + private OAuthServiceProvider m_oAuthServiceProvider; + private OAuthServiceConsumer m_oAuthServiceConsumer; + + public OAuthClientBase(OAuthServiceProvider provider, OAuthServiceConsumer consumer) { + m_oAuthServiceProvider = provider; + m_oAuthServiceConsumer = consumer; + } + + protected OAuthServiceProvider getProvider() { + return m_oAuthServiceProvider; + } + + protected OAuthServiceConsumer getConsumer() { + return m_oAuthServiceConsumer; + } + + protected OAuthAccessor createAccessor() { + String requestTokenUrl = m_oAuthServiceProvider.getRequestTokenURL(); + String authorizeTokenUrl = m_oAuthServiceProvider.getAuthorizeTokenURL(); + String accessTokenUrl = m_oAuthServiceProvider.getAccessTokenURL(); + + String callbackUrl = m_oAuthServiceConsumer.getCallbackUrl(); + String consumerKey = m_oAuthServiceConsumer.getConsumerKey(); + String consumerSecret = m_oAuthServiceConsumer.getConsumerSecret(); + + net.oauth.OAuthServiceProvider provider = + new net.oauth.OAuthServiceProvider(requestTokenUrl, authorizeTokenUrl, accessTokenUrl); + OAuthConsumer oAuthConsumer = new OAuthConsumer(callbackUrl, consumerKey, consumerSecret, provider); + return new OAuthAccessor(oAuthConsumer); + } + + protected OAuthMessage sendRequest(OAuthAccessor accessor, Map<String, String> map, String url) throws IOException, + URISyntaxException, OAuthException { + List<Map.Entry<String, String>> params = new ArrayList<Map.Entry<String, String>>(); + Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry<String, String> p = it.next(); + params.add(new OAuth.Parameter((String) p.getKey(), (String) p.getValue())); + } + net.oauth.client.OAuthClient client = new net.oauth.client.OAuthClient(new HttpClient4()); + return client.invoke(accessor, "GET", url, params); + } +} Added: trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/osgi/Activator.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/osgi/Activator.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,38 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.client.osgi; + +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; + +/** + * This is the activator for the authorization bundle + * @author ivol + */ +public class Activator extends DependencyActivatorBase { + + + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + } + + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } +} Added: trunk/amdatu-authentication/oauth-server/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/pom.xml Thu Dec 2 09:40:25 2010 @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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.amdatu</groupId> + <artifactId>org.amdatu.authentication</artifactId> + <version>0.0.6-SNAPSHOT</version> + </parent> + <groupId>org.amdatu.authentication.oauth</groupId> + <artifactId>server</artifactId> + <packaging>bundle</packaging> + <name>Amdatu Authentication - oAuth server</name> + <description>This bundle includes an API for oAuth service providers</description> + + <dependencies> + <dependency> + <groupId>org.amdatu.web</groupId> + <artifactId>httpcontext</artifactId> + <version>${platform.version}</version> + <scope>provided</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.web.rest</groupId> + <artifactId>jaxrs</artifactId> + <version>${platform.version}</version> + <scope>provided</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.authentication.oauth</groupId> + <artifactId>api</artifactId> + <version>${platform.version}</version> + <scope>provided</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.web</groupId> + <artifactId>httpcontext</artifactId> + <version>${platform.version}</version> + <scope>provided</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.4</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils</artifactId> + <version>1.8.3</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <version>3.2</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.amdatu.libraries</groupId> + <artifactId>utilities</artifactId> + <version>${platform.version}</version> + <scope>compile</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-Activator>org.amdatu.authentication.oauth.server.osgi.Activator</Bundle-Activator> + <Bundle-SymbolicName>org.amdatu.authentication.oauth.server</Bundle-SymbolicName> + <Export-Package>org.amdatu.authentication.oauth.server</Export-Package> + <Embed-Dependency>*;scope=compile</Embed-Dependency> + <DynamicImport-Package> + org.apache.log4j, + org.apache.avalon.framework.logger, + org.apache.log + </DynamicImport-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/ConsumerAlreadyExistsException.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/ConsumerAlreadyExistsException.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,25 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server; + +public class ConsumerAlreadyExistsException extends Exception { + private static final long serialVersionUID = -3147082163353782694L; + + public ConsumerAlreadyExistsException(String msg) { + super(msg); + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/ConsumerNotFoundException.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/ConsumerNotFoundException.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,24 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server; + +public class ConsumerNotFoundException extends Exception { + private static final long serialVersionUID = -6602963888588386204L; + public ConsumerNotFoundException(String msg) { + super(msg); + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthAccessTokenServlet.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthAccessTokenServlet.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,26 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server; + +import org.amdatu.authentication.oauth.server.service.OAuthResourceProviderImpl; + +public interface OAuthAccessTokenServlet { + /** + * The servlet alias of the access token servlet. + */ + final static String SERVLET_ALIAS = "/" + OAuthResourceProviderImpl.RESOURCE_ID + "/accesstoken"; +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthAuthorizeTokenServlet.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthAuthorizeTokenServlet.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,26 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server; + +import org.amdatu.authentication.oauth.server.service.OAuthResourceProviderImpl; + +public interface OAuthAuthorizeTokenServlet { + /** + * The servlet alias of the request token servlet. + */ + final static String SERVLET_ALIAS = "/" + OAuthResourceProviderImpl.RESOURCE_ID + "/authorizetoken"; +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthRequestTokenServlet.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthRequestTokenServlet.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,26 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server; + +import org.amdatu.authentication.oauth.server.service.OAuthResourceProviderImpl; + +public interface OAuthRequestTokenServlet { + /** + * The servlet alias of the request token servlet. + */ + final static String SERVLET_ALIAS = "/" + OAuthResourceProviderImpl.RESOURCE_ID + "/requesttoken"; +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthServiceConsumerRegistry.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthServiceConsumerRegistry.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,66 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; + +/** + * The oAuth server uses a service consumer registry to identify from which consumers + * token requests are received. Each token request holds the consumer key such that the + * oAuth server knows which consumer is asking for access. Tokens will only be distributed + * to service conusmers that are known in this registry. + * + * @author ivol + */ +public interface OAuthServiceConsumerRegistry { + /** + * Returns the oAuth service consumer matching the specified consumer key. If no such consumer could be found + * a ConsumerNotFoundException is thrown. + * @param consumerKey Key of the consumer to find + * @return The consumer if found + * @throws ConsumerNotFoundException If tno consumer could be found matching the specified consumer key + */ + OAuthServiceConsumer getConsumer(String consumerKey) throws ConsumerNotFoundException; + + /** + * Adds an oAuth service consumer to the registry of the oAuth server. A ConsumerAlreadyExistsException will be thrown + * if the consumer already exists. Note that each service consumer is uniquely identified by the consumer key + * (returned by getConsumerKey). + * + * @param consumer The OAuth service consumer to add + * @throws ConsumerAlreadyExistsException If a consumer with the same consumer key already exists + */ + void addConsumer(OAuthServiceConsumer consumer) throws ConsumerAlreadyExistsException; + + /** + * Removes an ooAuth service consumer from the registry of the oAuth server. The consumer that will be + * removed is the one that matches the consumer key of the specified consumer. + * + * @param consumer The oAith service consumer to remove + * @throws ConsumerNotFoundException if no consumer exists matching the consumer key of the specified consumer + */ + void removeConsumer(OAuthServiceConsumer consumer) throws ConsumerNotFoundException; + + /** + * Updates the properties of the specified oAuth service consumer. The consumer that will be updated is the one + * that matches the consumer key of the specified consumer. So the consumer key itself can never be updated. If + * you want to do so you will need to remove and add the consumer. + * @param consumer The oAith service consumer to update + * @throws ConsumerNotFoundException if no consumer exists matching the consumer key of the specified consumer + */ + void updateConsumer(OAuthServiceConsumer consumer) throws ConsumerNotFoundException; +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthTokenProvider.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthTokenProvider.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,104 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import net.oauth.OAuthAccessor; +import net.oauth.OAuthConsumer; +import net.oauth.OAuthException; +import net.oauth.OAuthMessage; +import net.oauth.OAuthProblemException; +import net.oauth.OAuthValidator; + +/** + * Interface of an oAuth token provider. A oAuth token provider provides request and access tokens and facilitates + * marking access token as authorized. + * @author ivol + * + */ +public interface OAuthTokenProvider { + /** + * Returns an oAtuth consumer that matched the consumer key as defined in the oAuth message. The oAuth message + * is generated from a normal http request, but contains only the oAuth headers that are relevant to oAuth. + * @param requestMessage The oAuth request message + * @return The consumer that matches the consumer key in the oAuth message + * @throws IOException + * @throws OAuthProblemException + */ + OAuthConsumer getConsumer(OAuthMessage requestMessage) throws IOException, OAuthProblemException; + + /** + * Returns the oAuth validator. The validator facilitates validating received oAuth messages. Validation includes + * checking if the token is expired, if the nonce is valid and if the provided (encrypted) consumer secret is correct. + * @return The OAuthValidator + */ + OAuthValidator getOAuthValidator(); + + /** + * Generates a new fresh request token for the given accessor. An accessor holds the service consumer and + * adds the request token, token secret and access token. + * @param accessor + * @throws OAuthException + */ + void generateRequestToken(OAuthAccessor accessor) throws OAuthException; + + /** + * An accessor contains provided tokens for a specific service consumer. When a request token is generated, an + * accessor is added for the service consumer holding the request token and token secret. So an accessor is a + * kind of 'oAuth session'. When the request token is authorized, the access token is added to the accessor. + * This method returns the accessor from the given oAuth message, which holds the relevant oAuth headers + * posted in the oAuth request. + * @return The accessor, holding the distributed tokens for a particular oAuth session for a service consumer + */ + OAuthAccessor getAccessor(OAuthMessage requestMessage) throws IOException, OAuthProblemException; + + /** + * Handles an exception thrown by any token servlet. + * @param e + * @param request + * @param response + * @param sendBody + * @throws IOException + * @throws ServletException + */ + void handleException(Exception e, HttpServletRequest request, HttpServletResponse response, + boolean sendBody) throws IOException, ServletException; + + /** + * Marks the request token as authorized. The accessor represents the generated tokens for the service + * consumer and the userId + * @param accessor + * @param userId + * @throws OAuthException + */ + void markAsAuthorized(OAuthAccessor accessor, String userId) throws OAuthException; + + + /** + * Exchange the request token for an access token. This call is typically invoked after a request token + * has been authorized, however this method does not validate that. The token servlets are supposed to + * perform all token validations. + * + * @throws OAuthException + */ + void generateAccessToken(OAuthAccessor accessor) throws OAuthException; +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/osgi/Activator.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/osgi/Activator.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,113 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.osgi; + +import java.util.Dictionary; +import java.util.Hashtable; + +import javax.servlet.Servlet; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.authentication.oauth.api.OAuthServiceProvider; +import org.amdatu.authentication.oauth.server.OAuthAccessTokenServlet; +import org.amdatu.authentication.oauth.server.OAuthAuthorizeTokenServlet; +import org.amdatu.authentication.oauth.server.OAuthRequestTokenServlet; +import org.amdatu.authentication.oauth.server.OAuthServiceConsumerRegistry; +import org.amdatu.authentication.oauth.server.OAuthTokenProvider; +import org.amdatu.authentication.oauth.server.service.OAuthAccessTokenServletImpl; +import org.amdatu.authentication.oauth.server.service.OAuthAuthorizeTokenServletImpl; +import org.amdatu.authentication.oauth.server.service.OAuthRequestTokenServletImpl; +import org.amdatu.authentication.oauth.server.service.OAuthResourceProviderImpl; +import org.amdatu.authentication.oauth.server.service.OAuthServiceConsumerRegistryImpl; +import org.amdatu.authentication.oauth.server.service.OAuthServiceConsumerRegistryREST; +import org.amdatu.authentication.oauth.server.service.OAuthServiceProviderImpl; +import org.amdatu.authentication.oauth.server.service.OAuthTokenProviderImpl; +import org.amdatu.web.httpcontext.HttpContextServiceFactory; +import org.amdatu.web.httpcontext.ResourceProvider; +import org.apache.felix.dm.Component; +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; +import org.osgi.service.cm.ManagedService; +import org.osgi.service.log.LogService; + +/** + * This is the activator for the authorization bundle + * @author ivol + */ +public class Activator extends DependencyActivatorBase { + + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + // Create and register the OAuth token provider service component. + manager.add( + createComponent() + .setInterface(OAuthTokenProvider.class.getName(), null) + .setImplementation(OAuthTokenProviderImpl.class) + .add(createServiceDependency().setService(LogService.class).setRequired(true)) + .add(createServiceDependency().setService(OAuthServiceConsumer.class).setCallbacks("onAdded", "onRemoved"))); + + // Create and register the resource provider + manager.add( + createComponent() + .setInterface(ResourceProvider.class.getName(), null) + .setImplementation(OAuthResourceProviderImpl.class) + .add(createServiceDependency().setService(HttpContextServiceFactory.class).setRequired(true))); + + // Create and register the OAuth service provider + manager.add( + createComponent() + .setInterface(new String[]{OAuthServiceProvider.class.getName(), ManagedService.class.getName()}, null) + .setImplementation(OAuthServiceProviderImpl.class) + .add(createConfigurationDependency().setPid(OAuthServiceProviderImpl.PID))); + + // Create and register the oAuth service consumer registry service + manager.add( + createComponent() + .setInterface(OAuthServiceConsumerRegistry.class.getName(), null) + .setImplementation(OAuthServiceConsumerRegistryImpl.class) + .add(createServiceDependency().setService(LogService.class).setRequired(true))); + + // Create and register the oAuth service consumer registry REST service + manager.add( + createComponent() + .setInterface(ResourceProvider.class.getName(), null) + .setImplementation(OAuthServiceConsumerRegistryREST.class) + .add(createServiceDependency().setService(LogService.class).setRequired(true)) + .add(createServiceDependency().setService(OAuthServiceConsumerRegistry.class).setRequired(true))); + + // Create and register the OAuth servlet components. + manager.add(createComponent(OAuthRequestTokenServlet.SERVLET_ALIAS, OAuthRequestTokenServlet.class, OAuthRequestTokenServletImpl.class)); + manager.add(createComponent(OAuthAuthorizeTokenServlet.SERVLET_ALIAS, OAuthAuthorizeTokenServlet.class, OAuthAuthorizeTokenServletImpl.class)); + manager.add(createComponent(OAuthAccessTokenServlet.SERVLET_ALIAS, OAuthAccessTokenServlet.class, OAuthAccessTokenServletImpl.class)); + } + + private Component createComponent(String alias, Class<?> servletInterface, Class<?> servletClass) { + Dictionary<String, String> servletProperties = new Hashtable<String, String>(); + servletProperties.put("alias", alias); + servletProperties.put("contextId", alias); + return createComponent() + .setInterface(new String[]{servletInterface.getName(), Servlet.class.getName()}, servletProperties) + .setImplementation(servletClass) + .add(createServiceDependency().setService(OAuthTokenProvider.class).setRequired(true)) + .add(createServiceDependency().setService(LogService.class).setRequired(true)); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthAccessTokenServletImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthAccessTokenServletImpl.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,90 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthMessage; +import net.oauth.OAuthProblemException; +import net.oauth.server.OAuthServlet; + +import org.amdatu.authentication.oauth.server.OAuthAccessTokenServlet; +import org.amdatu.authentication.oauth.server.OAuthTokenProvider; +import org.osgi.service.log.LogService; + +public class OAuthAccessTokenServletImpl extends HttpServlet implements OAuthAccessTokenServlet { + // The serial version UID of this servlet + private static final long serialVersionUID = -4119232615154952483L; + + // Service dependencies, injected by the Felix dependency manager + private volatile LogService m_logService; + private volatile OAuthTokenProvider m_tokenProvider; + + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + processRequest(request, response); + } + + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + processRequest(request, response); + } + + public void processRequest(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + try { + OAuthMessage requestMessage = OAuthServlet.getMessage(request, null); + OAuthAccessor accessor = m_tokenProvider.getAccessor(requestMessage); + m_logService.log(LogService.LOG_DEBUG, "Access token requested for accessor " + accessor.consumer.consumerKey); + + m_tokenProvider.getOAuthValidator().validateMessage(requestMessage, accessor); + + // make sure token is authorized + if (!Boolean.TRUE.equals(accessor.getProperty("authorized"))) { + OAuthProblemException problem = new OAuthProblemException("permission_denied"); + throw problem; + } + // generate access token and secret + m_tokenProvider.generateAccessToken(accessor); + m_logService.log(LogService.LOG_DEBUG, "Generated access token " + accessor.accessToken); + + response.setContentType("text/plain"); + OutputStream out = null; + try { + out = response.getOutputStream(); + OAuth.formEncode(OAuth.newList("oauth_token", accessor.accessToken, "oauth_token_secret", + accessor.tokenSecret), out); + } + finally { + if (out != null) { + out.close(); + } + } + } + catch (Exception e) { + m_tokenProvider.handleException(e, request, response, true); + } + } +} \ No newline at end of file Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthAuthorizeTokenServletImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthAuthorizeTokenServletImpl.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,147 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthMessage; +import net.oauth.server.OAuthServlet; + +import org.amdatu.authentication.oauth.server.OAuthAuthorizeTokenServlet; +import org.amdatu.authentication.oauth.server.OAuthTokenProvider; +import org.osgi.service.log.LogService; + +public class OAuthAuthorizeTokenServletImpl extends HttpServlet implements OAuthAuthorizeTokenServlet { + // The serial version UID of this servlet + private static final long serialVersionUID = -3589350956712947896L; + + // Service dependencies, injected by the Felix dependency manager + private volatile LogService m_logService; + private volatile OAuthTokenProvider m_tokenProvider; + + public void init(ServletConfig config) throws ServletException { + super.init(config); + } + + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + try { + OAuthMessage requestMessage = OAuthServlet.getMessage(request, null); + OAuthAccessor accessor = m_tokenProvider.getAccessor(requestMessage); + if (Boolean.TRUE.equals(accessor.getProperty("authorized"))) { + // already authorized send the user back + m_logService.log(LogService.LOG_DEBUG, "Token authorized, redirecting user to callback url"); + returnToConsumer(request, response, accessor); + } + else { + m_logService.log(LogService.LOG_DEBUG, "Authorize token request received, redirecting user to authorization page"); + sendToAuthorizePage(request, response, accessor); + } + } + catch (Exception e) { + m_tokenProvider.handleException(e, request, response, true); + } + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + try { + OAuthMessage requestMessage = OAuthServlet.getMessage(request, null); + OAuthAccessor accessor = m_tokenProvider.getAccessor(requestMessage); + String userId = request.getParameter("userId"); + if (userId == null) { + sendToAuthorizePage(request, response, accessor); + } + // set userId in accessor and mark it as authorized + m_tokenProvider.markAsAuthorized(accessor, userId); + returnToConsumer(request, response, accessor); + } + catch (Exception e) { + m_tokenProvider.handleException(e, request, response, true); + } + } + + private void sendToAuthorizePage(HttpServletRequest request, HttpServletResponse response, OAuthAccessor accessor) + throws IOException, ServletException { + String callback = request.getParameter("oauth_callback"); + if (callback == null || callback.length() <= 0) { + callback = "none"; + } + String consumer_description = (String) accessor.consumer.getProperty("description"); + request.setAttribute("CONS_DESC", consumer_description); + request.setAttribute("CALLBACK", callback); + request.setAttribute("TOKEN", accessor.requestToken); + String authorizeJsp = OAuthResourceProviderImpl.RESOURCE_ID + "/jsp/authorize.jsp"; + m_logService.log(LogService.LOG_DEBUG, "Forwarding authorize token request to " + authorizeJsp + + ", token=" + accessor.requestToken + ", callback=" + callback); + + // Create a request wrapper returning the path of the JSP servlet instead of this servlet + HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request) { + public String getPathInfo() { + return "/" + OAuthResourceProviderImpl.RESOURCE_ID + "/jsp/authorize.jsp"; + } + }; + + // Dispatch the request to the authorize JSP + request.getRequestDispatcher("/" + authorizeJsp).forward(wrapper, response); + } + + private void returnToConsumer(HttpServletRequest request, + HttpServletResponse response, OAuthAccessor accessor) + throws IOException, ServletException { + // send the user back to site's callBackUrl + String callback = request.getParameter("oauth_callback"); + if ("none".equals(callback) + && accessor.consumer.callbackURL != null + && accessor.consumer.callbackURL.length() > 0) { + // first check if we have something in our properties file + callback = accessor.consumer.callbackURL; + } + + if ("none".equals(callback)) { + // no call back it must be a client + response.setContentType("text/plain"); + PrintWriter out = response.getWriter(); + out.println("You have successfully authorized '" + + accessor.consumer.getProperty("description") + + "'. Please close this browser window and click continue" + + " in the client."); + out.close(); + } + else { + // if callback is not passed in, use the callback from config + if (callback == null || callback.length() <= 0) + callback = accessor.consumer.callbackURL; + String token = accessor.requestToken; + if (token != null) { + callback = OAuth.addParameters(callback, "oauth_token", token); + } + + response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); + response.setHeader("Location", callback); + } + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthRequestTokenServletImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthRequestTokenServletImpl.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,103 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthConsumer; +import net.oauth.OAuthMessage; + +import org.amdatu.authentication.oauth.server.OAuthRequestTokenServlet; +import org.amdatu.authentication.oauth.server.OAuthTokenProvider; +import org.osgi.service.log.LogService; + +/** + * This servlet is responsible for generating request tokens. + * Endpoint: /oauth-server/requesttoken + * @author ivol + */ +public class OAuthRequestTokenServletImpl extends HttpServlet implements OAuthRequestTokenServlet { + /** + * The serial version UID of this servlet. + */ + private static final long serialVersionUID = -1035130593268947357L; + + // Service dependencies, injected by the Felix dependency manager + private volatile LogService m_logService; + private volatile OAuthTokenProvider m_tokenProvider; + + public void start() { + m_logService.log(LogService.LOG_DEBUG, "OAuth Request Token servlet started."); + } + + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + processRequest(request, response); + } + + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + processRequest(request, response); + } + + public void processRequest(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + try { + // Create the oAuth request message and retrieve the consumer from the consumer key + // as specified in the oAuth header + OAuthMessage requestMessage = net.oauth.server.OAuthServlet.getMessage(request, null); + OAuthConsumer consumer = m_tokenProvider.getConsumer(requestMessage); + m_logService.log(LogService.LOG_DEBUG, "Request token requested for consumer '" + consumer.consumerKey + "'"); + + // Create an accessor for the consumer, the accessor represents the actual client + // using the service consumer. + OAuthAccessor accessor = new OAuthAccessor(consumer); + m_tokenProvider.getOAuthValidator().validateMessage(requestMessage, accessor); + + // Support the 'Variable Accessor Secret' extension + // described in http://oauth.pbwiki.com/AccessorSecret + String secret = requestMessage.getParameter("oauth_accessor_secret"); + if (secret != null) { + accessor.setProperty(OAuthConsumer.ACCESSOR_SECRET, secret); + } + + // Generate request_token and secret + m_tokenProvider.generateRequestToken(accessor); + m_logService.log(LogService.LOG_DEBUG, "Request token '" + accessor.requestToken + "' assigned to accessor"); + + response.setContentType("text/plain"); + OutputStream out = null; + try { + out = response.getOutputStream(); + OAuth.formEncode(OAuth.newList("oauth_token", accessor.requestToken, "oauth_token_secret", accessor.tokenSecret), out); + } finally { + out.close(); + } + } + catch (Exception e) { + m_tokenProvider.handleException(e, request, response, true); + } + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthResourceProviderImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthResourceProviderImpl.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,59 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.net.URL; + +import org.amdatu.web.httpcontext.HttpContextServiceFactory; +import org.amdatu.web.httpcontext.ResourceProvider; +import org.apache.felix.dm.Component; +import org.osgi.framework.BundleContext; + +public class OAuthResourceProviderImpl implements ResourceProvider { + // The resource id + public final static String RESOURCE_ID = "oauth-server"; + + private volatile HttpContextServiceFactory m_httpContextFactoryService; + private volatile BundleContext m_bundleContext; + + private Component m_httpContextComponent; + + /** + * The init() method is invoked by the Felix dependency manager. + */ + public void init() { + // Create our own http context and register resources + m_httpContextComponent = m_httpContextFactoryService.create(m_bundleContext, this); + + } + + /** + * The destroy() method is invoked by the Felix dependency manager. + */ + public void destroy() { + m_httpContextComponent.stop(); + } + + + public URL getResource(String name) { + return null; + } + + public String getResourceId() { + return RESOURCE_ID; + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerBean.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerBean.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,84 @@ +package org.amdatu.authentication.oauth.server.service; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; + +import javax.ws.rs.core.UriInfo; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.libraries.utilities.rest.AtomSyndicationLink; +import org.apache.commons.beanutils.BeanUtils; + + at SuppressWarnings("restriction") + at XmlRootElement(name = "consumer") + at XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) +public class OAuthServiceConsumerBean implements OAuthServiceConsumer { + + private String m_consumerKey; + + private String m_consumerSecret; + + private String m_name; + + private String m_callbackUrl; + + private AtomSyndicationLink m_link; + + public String getConsumerKey() { + return m_consumerKey; + } + + public void setConsumerKey(String consumerKey) { + m_consumerKey = consumerKey; + } + + public String getConsumerSecret() { + return m_consumerSecret; + } + + public void setConsumerSecret(String consumerSecret) { + m_consumerSecret = consumerSecret; + } + + public String getName() { + return m_name; + } + + public void setName(String name) { + m_name = name; + } + + public String getCallbackUrl() { + return m_callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + m_callbackUrl = callbackUrl; + } + + public AtomSyndicationLink getLink() { + return m_link; + } + + public void setLink(AtomSyndicationLink link) { + m_link = link; + } + + private void addLink(URI link, String rel) { + setLink(new AtomSyndicationLink().setRel(rel).setHref(link.toString())); + } + + public static OAuthServiceConsumerBean copy(OAuthServiceConsumer consumer, UriInfo uriInfo) + throws IllegalAccessException, InvocationTargetException { + OAuthServiceConsumerBean bean = new OAuthServiceConsumerBean(); + BeanUtils.copyProperties(bean, consumer); + URI thisLink = uriInfo.getAbsolutePathBuilder().build(); + bean.addLink(thisLink, "alternate"); + return bean; + } + + +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerRegistryImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerRegistryImpl.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,73 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.util.HashMap; +import java.util.Map; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.authentication.oauth.server.ConsumerAlreadyExistsException; +import org.amdatu.authentication.oauth.server.ConsumerNotFoundException; +import org.amdatu.authentication.oauth.server.OAuthServiceConsumerRegistry; +import org.osgi.service.log.LogService; + +public class OAuthServiceConsumerRegistryImpl implements OAuthServiceConsumerRegistry { + Map<String, OAuthServiceConsumer> m_consumers = new HashMap<String, OAuthServiceConsumer>(); + private LogService m_logService; + + public void start() { + m_logService.log(LogService.LOG_DEBUG, "Oauth Service Consumer registry available"); + + OAuthServiceConsumerBean bean = new OAuthServiceConsumerBean(); + bean.setConsumerKey("test"); + bean.setName("Test consumer inc."); + bean.setConsumerSecret("thisissecret"); + bean.setCallbackUrl("http://callmeback"); + m_consumers.put("test", bean); + } + public OAuthServiceConsumer getConsumer(String consumerKey) throws ConsumerNotFoundException { + if (m_consumers.containsKey(consumerKey)) { + return m_consumers.get(consumerKey); + } else { + throw new ConsumerNotFoundException("Consumer with key '" + consumerKey + "' doesn't exist"); + } + } + + public void addConsumer(OAuthServiceConsumer consumer) throws ConsumerAlreadyExistsException { + if (m_consumers.containsKey(consumer.getConsumerKey())) { + throw new ConsumerAlreadyExistsException("Consumer with key '" + consumer.getConsumerKey() + "' already exists"); + } else { + m_consumers.put(consumer.getConsumerKey(), consumer); + } + } + + public void removeConsumer(OAuthServiceConsumer consumer) throws ConsumerNotFoundException { + if (!m_consumers.containsKey(consumer.getConsumerKey())) { + throw new ConsumerNotFoundException("Consumer with key '" + consumer.getConsumerKey() + "' doesn't exist"); + } else { + m_consumers.remove(consumer.getConsumerKey()); + } + } + + public void updateConsumer(OAuthServiceConsumer consumer) throws ConsumerNotFoundException { + if (!m_consumers.containsKey(consumer.getConsumerKey())) { + throw new ConsumerNotFoundException("Consumer with key '" + consumer.getConsumerKey() + "' doesn't exist"); + } else { + m_consumers.put(consumer.getConsumerKey(), consumer); + } + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerRegistryREST.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceConsumerRegistryREST.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,141 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.lang.reflect.InvocationTargetException; +import java.net.URL; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.authentication.oauth.server.ConsumerAlreadyExistsException; +import org.amdatu.authentication.oauth.server.ConsumerNotFoundException; +import org.amdatu.authentication.oauth.server.OAuthServiceConsumerRegistry; +import org.amdatu.web.httpcontext.ResourceProvider; +import org.osgi.service.log.LogService; + +/** + * This class provides a REST interface on top of the oAuth service consumer registry + * @author ivol + * + */ + at Path("oauth/consumers") +public class OAuthServiceConsumerRegistryREST implements ResourceProvider { + // The oAuth service consumer registry + private volatile OAuthServiceConsumerRegistry m_registry; + private volatile LogService m_logService; + + public void start() { + m_logService.log(LogService.LOG_DEBUG, "OAuth Service Consumer registry REST service started."); + } + + /** + * REST interface: GET /rest/services/oauth/consumers/oauth/consumers/{consumerKey} + * Returns the requested consumer in application/xml or application/json format. + * @param consumerKey The key of the consumer to retrieve. + * @return The consumer matching the key in xml or json format + */ + @GET + @Path("{consumerKey}") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public OAuthServiceConsumer getConsumer(@PathParam("consumerKey") final String consumerKey, @Context UriInfo uriInfo) { + try { + return OAuthServiceConsumerBean.copy(m_registry.getConsumer(consumerKey), uriInfo); + } + catch (ConsumerNotFoundException e) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + catch (IllegalAccessException e) { + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + catch (InvocationTargetException e) { + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + /** + * REST interface: PUT /rest/services/oauth/consumers/oauth/consumers + * Adds a new consumer with the properties of the posted values in application/xml or application/json format. + * @return The http response object + */ + @PUT + @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response addConsumer(OAuthServiceConsumerBean consumer) { + try { + m_registry.addConsumer(consumer); + return Response.ok().build(); + } + catch (ConsumerAlreadyExistsException e) { + throw new WebApplicationException(Response.Status.NOT_MODIFIED); + } + } + + /** + * REST interface: PUT /rest/services/oauth/consumers/oauth/consumers/{consumerKey} + * Updates an existing consumer with the properties of the posted values in application/xml or application/json format. + * @param consumerKey The key of the consumer to update. + * @return The http response object + */ + @PUT + @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + @Path("{consumerKey}") + public Response updateConsumer(@PathParam("consumerKey") final String consumerKey, OAuthServiceConsumerBean consumer) { + try { + m_registry.updateConsumer(consumer); + return Response.ok().build(); + } + catch (ConsumerNotFoundException e) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + } + + + /** + * REST interface: PUT /rest/services/oauth/consumers/oauth/consumers + * Adds a new consumer with the properties of the posted values in application/xml or application/json format. + * @return The http response object + */ + @DELETE + public Response deleteConsumer(@PathParam("consumerKey") final String consumerKey) { + try { + m_registry.removeConsumer(m_registry.getConsumer(consumerKey)); + return Response.ok().build(); + } + catch (ConsumerNotFoundException e) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + } + + public URL getResource(String name) { + return null; + } + + public String getResourceId() { + return "oauth/consumers"; + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceProviderImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServiceProviderImpl.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,79 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.util.Dictionary; + +import org.amdatu.authentication.oauth.api.OAuthServiceProvider; +import org.amdatu.authentication.oauth.server.OAuthAccessTokenServlet; +import org.amdatu.authentication.oauth.server.OAuthAuthorizeTokenServlet; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; + +public class OAuthServiceProviderImpl implements OAuthServiceProvider, ManagedService { + // The PID and configuration properties + public final static String PID = "org.amdatu.authentication.oauth.server"; + private final static String HOSTNAME = "hostname"; + private final static String PORTNR = "portnr"; + + private String m_hostName, m_portNr; + + public String getRequestTokenURL() { + if (m_hostName != null && m_portNr != null) { + return "http://" + m_hostName + ":" + m_portNr + OAuthRequestTokenServletImpl.SERVLET_ALIAS; + } + else { + return null; + } + } + + public String getAuthorizeTokenURL() { + if (m_hostName != null && m_portNr != null) { + return "http://" + m_hostName + ":" + m_portNr + OAuthAuthorizeTokenServlet.SERVLET_ALIAS; + } + else { + return null; + } + } + + public String getAccessTokenURL() { + if (m_hostName != null && m_portNr != null) { + return "http://" + m_hostName + ":" + m_portNr + OAuthAccessTokenServlet.SERVLET_ALIAS; + } + else { + return null; + } + } + + @SuppressWarnings("unchecked") + public void updated(Dictionary dictionary) throws ConfigurationException { + if (dictionary != null) { + checkAvailability(dictionary, new String[] { HOSTNAME, PORTNR }); + m_hostName = (String) dictionary.get(HOSTNAME); + m_portNr = (String) dictionary.get(PORTNR); + } + } + + @SuppressWarnings("unchecked") + private void checkAvailability(Dictionary dictionary, String[] mandatoryKeys) throws ConfigurationException { + for (String mandatoryKey : mandatoryKeys) { + if (dictionary.get(mandatoryKey) == null) { + throw new ConfigurationException("Missing configuration key", mandatoryKey); + } + } + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServlet.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServlet.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,25 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + + +/** + * This service is responsible for authorization handling, based on the UserAdmin OSGi service. + * @author ivol + */ +public class OAuthServlet { +} Added: trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthTokenProviderImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthTokenProviderImpl.java Thu Dec 2 09:40:25 2010 @@ -0,0 +1,194 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package org.amdatu.authentication.oauth.server.service; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import net.oauth.OAuthAccessor; +import net.oauth.OAuthConsumer; +import net.oauth.OAuthException; +import net.oauth.OAuthMessage; +import net.oauth.OAuthProblemException; +import net.oauth.OAuthValidator; +import net.oauth.SimpleOAuthValidator; +import net.oauth.server.OAuthServlet; + +import org.amdatu.authentication.oauth.api.OAuthServiceConsumer; +import org.amdatu.authentication.oauth.server.OAuthTokenProvider; +import org.apache.commons.codec.digest.DigestUtils; +import org.osgi.service.log.LogService; + +public class OAuthTokenProviderImpl implements OAuthTokenProvider { + // Service dependencies injected by the dependency manager + private volatile LogService m_logService; + + public OAuthValidator m_oAuthValidator = new SimpleOAuthValidator(); + + private Map<String, OAuthConsumer> m_oAuthConsumers = + Collections.synchronizedMap(new HashMap<String, OAuthConsumer>(10)); + + private Collection<OAuthAccessor> m_tokens = new HashSet<OAuthAccessor>(); + + public void start() { + m_logService.log(LogService.LOG_DEBUG, "OAuthTokenProvider service started"); + } + + public void onAdded(OAuthServiceConsumer oAuthService) { + OAuthConsumer consumer = new OAuthConsumer( + oAuthService.getCallbackUrl(), + oAuthService.getConsumerKey(), + oAuthService.getConsumerSecret(), + null); + consumer.setProperty("description", oAuthService.getName()); + m_oAuthConsumers.put(oAuthService.getConsumerKey(), consumer); + m_logService.log(LogService.LOG_DEBUG, "New OAuthServiceConsumer registered with key " + + oAuthService.getConsumerKey()); + } + + public void onRemoved(OAuthServiceConsumer oAuthService) { + m_oAuthConsumers.remove(oAuthService.getConsumerKey()); + m_logService.log(LogService.LOG_DEBUG, "OAuthServiceConsumer with key " + oAuthService.getConsumerKey() + + " was removed"); + } + + public synchronized OAuthConsumer getConsumer(OAuthMessage requestMessage) throws IOException, + OAuthProblemException { + OAuthConsumer consumer = null; + + // try to load from local cache if not throw exception + String consumer_key = requestMessage.getConsumerKey(); + consumer = m_oAuthConsumers.get(consumer_key); + if (consumer == null) { + OAuthProblemException problem = new OAuthProblemException("token_rejected"); + throw problem; + } + return consumer; + } + + public OAuthValidator getOAuthValidator() { + return m_oAuthValidator; + } + + /** + * Generate a fresh request token and secret for a consumer. + * + * @throws OAuthException + */ + public synchronized void generateRequestToken(OAuthAccessor accessor) throws OAuthException { + // generate oauth_token and oauth_secret + String consumer_key = (String) accessor.consumer.getProperty("name"); + // generate token and secret based on consumer_key + + // for now use md5 of name + current time as token + String token_data = consumer_key + System.nanoTime(); + String token = DigestUtils.md5Hex(token_data); + // for now use md5 of name + current time + token as secret + String secret_data = consumer_key + System.nanoTime() + token; + String secret = DigestUtils.md5Hex(secret_data); + + accessor.requestToken = token; + accessor.tokenSecret = secret; + accessor.accessToken = null; + + // add to the local cache + m_tokens.add(accessor); + } + + /** + * Get the access token and token secret for the given oauth_token. + */ + public synchronized OAuthAccessor getAccessor(OAuthMessage requestMessage) throws IOException, + OAuthProblemException { + // try to load from local cache if not throw exception + String consumer_token = requestMessage.getToken(); + OAuthAccessor accessor = null; + for (OAuthAccessor a : m_tokens) { + if (a.requestToken != null) { + if (a.requestToken.equals(consumer_token)) { + accessor = a; + break; + } + } + else if (a.accessToken != null) { + if (a.accessToken.equals(consumer_token)) { + accessor = a; + break; + } + } + } + + if (accessor == null) { + OAuthProblemException problem = new OAuthProblemException("token_expired"); + throw problem; + } + + return accessor; + } + + /** + * Set the access token + */ + public synchronized void markAsAuthorized(OAuthAccessor accessor, String userId) throws OAuthException { + // first remove the accessor from cache + m_tokens.remove(accessor); + + accessor.setProperty("user", userId); + accessor.setProperty("authorized", Boolean.TRUE); + + // update token in local cache + m_tokens.add(accessor); + } + + /** + * Generate a fresh request token and secret for a consumer. + * + * @throws OAuthException + */ + public synchronized void generateAccessToken(OAuthAccessor accessor) throws OAuthException { + // generate oauth_token and oauth_secret + String consumer_key = (String) accessor.consumer.getProperty("name"); + // generate token and secret based on consumer_key + + // for now use md5 of name + current time as token + String token_data = consumer_key + System.nanoTime(); + String token = DigestUtils.md5Hex(token_data); + // first remove the accessor from cache + m_tokens.remove(accessor); + + accessor.requestToken = null; + accessor.accessToken = token; + + // update token in local cache + m_tokens.add(accessor); + } + + public synchronized void handleException(Exception e, HttpServletRequest request, HttpServletResponse response, + boolean sendBody) throws IOException, ServletException { + String realm = (request.isSecure())?"https://":"http://"; + realm += request.getLocalName(); + OAuthServlet.handleException(response, e, realm, sendBody); + } +} Added: trunk/amdatu-authentication/oauth-server/src/main/resources/jsp/authorize.jsp ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/oauth-server/src/main/resources/jsp/authorize.jsp Thu Dec 2 09:40:25 2010 @@ -0,0 +1,34 @@ +<%@page contentType="text/html"%> +<%@page pageEncoding="UTF-8"%> +<% + String appDesc = (String)request.getAttribute("CONS_DESC"); + String token = (String)request.getAttribute("TOKEN"); + String callback = (String)request.getAttribute("CALLBACK"); + if(callback == null) + callback = ""; + +%> + +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title>Your Friendly OAuth Provider</title> + </head> + <body> + <jsp:include page="banner.jsp"/> + + <h3>"<%=appDesc%>" is trying to access your information.</h3> + + Enter the userId you want to be known as: + <form name="authZForm" action=" /newoauth/authorizetoken" method="POST"> + <input type="text" name="userId" value="" size="20" /><br> + <input type="hidden" name="oauth_token" value="<%= token %>"/> + <input type="hidden" name="oauth_callback" value="<%= callback %>"/> + <input type="submit" name="Authorize" value="Authorize"/> + </form> + + </body> +</html> Added: trunk/amdatu-authentication/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-authentication/pom.xml Thu Dec 2 09:40:25 2010 @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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.amdatu</groupId> + <artifactId>amdatu</artifactId> + <version>0.0.6-SNAPSHOT</version> + </parent> + <artifactId>org.amdatu.authentication</artifactId> + <name>Amdatu Authentication</name> + <description>This module consists of all Authentication related bundles</description> + <packaging>pom</packaging> + + <dependencies> + <dependency> + <groupId>servletapi</groupId> + <artifactId>servletapi</artifactId> + <version>2.4</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <modules> + <module>oauth-api</module> + <module>oauth-client</module> + <module>oauth-server</module> + </modules> + +</project> \ No newline at end of file
