diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index d00c8e5..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,18 +0,0 @@ -# ToopherAPI Java Client - -#### Java Version ->=5.0 (originally numbered 1.5) - -#### Installing Dependencies -Toopher uses [Maven](http://maven.apache.org/). - -To install Maven with Homebrew run: -```shell -$ brew install maven -``` - -#### Tests -To run the tests enter: -```shell -$ mvn test -``` diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..ac87d1c --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,7 @@ +Copyright (c) 2012 Toopher, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README-Iframe.md b/README-Iframe.md deleted file mode 100644 index f999ca9..0000000 --- a/README-Iframe.md +++ /dev/null @@ -1,181 +0,0 @@ -# Authenticating using the Toopher `iframe` - -Toopher's `iframe`-based authentication flow is the simplest way for web developers to integrate Toopher Two-Factor Authentication into an application. - -## Toopher `iframe` Authentication Overview - -The `iframe`-based authentication flow works by inserting an ` - -There is no difference in the markup required for a Pairing vs. an Authentication `iframe` request (the generated URI embeds all relevant information). - -## Examples - -### All-in-one iframe - -#### Generating an iframe URI - -Every Toopher Authentication session should include a unique `requestToken` - a randomized `String` that is included in the signed request to the Toopher API and returned in the signed response from the Toopher `iframe`. To guard against potential replay attacks, your code should validate that the returned `requestToken` is the same one used to create the request. - -Creating a random request token and storing it in the server-side session using the Java Servlet API: - - private static final SecureRandom secureRandom = new SecureRandom(); - // simple way to generate a randomized string. - String requestToken = new BigInteger(20 * 8, secureRandom).toString(32); - request.getSession().setAttribute("ToopherRequestToken", requestToken); - -The Toopher Authentication API provides the requester a rich set of controls over authentication parameters. - - String authIframeUrl = iframeApi.authUri(userName, resetEmail, actionName, automationAllowed, challengeRequired, requestToken, requesterMetadata, ttl); - -For the simple case of authenticating a user at login, a `loginIframeUrl` helper method is available: - - String loginIframeUrl = iframeApi.loginUri(userName, resetEmail, requestToken) - -When the the `iframe` is served this way Toopher will determine if the -input `userName` is already paired; if they have not, we will show the -*Pairing* steps. After the user has paired the *Authentication* steps will be shown. - -#### Validating postback data from the iframe and parsing API errors - -In this example, `data` is a `Map` of the form data POSTed to your server from the Toopher Authentication `iframe`. You should replace the commented blocks with code appropriate for the condition described in the comment. - - Map data = httpServletRequest.getParameterMap(); - String requestToken = (String)request.getSession().getAttribute("ToopherRequestToken"); - // invalidate the Request Token to guard against replay attacks - request.getSession().removeAttribute("ToopherRequestToken"); - - try { - Map validatedData = iframeApi.validate(data, requestToken); - if (validatedData.containsKey("error_code")) { - String errorCode = validatedData.get("error_code"); - // There was an error -- user should not be authenticated - } else { - // Signature is valid with no api errors -- check authentication result - boolean authPending = validatedData.get("pending").toLowerCase().equals("true"); - boolean authGranted = validatedData.get("granted").toLowerCase().equals("true"); - - // authenticationResult is the ultimate result of Toopher second-factor authentication - boolean authenticationResult = authGranted && !authPending; - if (authenticationResults) { - // Log user in - } else { - // Fail authentication attempt - } - } - } catch (ToopherIframe.SignatureValidationError e) { - // Signature was invalid -- user should not be authenticated - // - // e.getMessage() will return more information about what specifically - // went wrong (incorrect session token, expired TTL, invalid signature) - } - -### Separate Pairing and Authentication iframes - -#### Generating an Authentication iframe URI - -Every Toopher Authentication session should include a unique `requestToken` - a randomized `String` that is included in the signed request to the Toopher API and returned in the signed response from the Toopher `iframe`. To guard against potential replay attacks, your code should validate that the returned `requestToken` is the same one used to create the request. - -Creating a random request token and storing it in the server-side session using the Java Servlet API: - - private static final SecureRandom secureRandom = new SecureRandom(); - // simple way to generate a randomized string. - String requestToken = new BigInteger(20 * 8, secureRandom).toString(32); - request.getSession().setAttribute("ToopherRequestToken", requestToken); - -The Toopher Authentication API provides the requester a rich set of controls over authentication parameters. - - String authIframeUrl = iframeApi.authUri(userName, resetEmail, actionName, automationAllowed, challengeRequired, requestToken, requesterMetadata, ttl); - -For the simple case of authenticating a user at login, a `loginIframeUrl` helper method is available: - - String loginIframeUrl = iframeApi.loginUri(userName, resetEmail, requestToken) - -#### Generating a Pairing iframe URI - - String pairIframeUrl = iframeApi.pairUri(userName, resetEmail) - -#### Validating postback data from Authentication iframe and parsing API errors - -In this example, `data` is a `Map` of the form data POSTed to your server from the Toopher Authentication `iframe`. You should replace the commented blocks with code appropriate for the condition described in the comment. - - Map data = httpServletRequest.getParameterMap(); - String requestToken = (String)request.getSession().getAttribute("ToopherRequestToken"); - // invalidate the Request Token to guard against replay attacks - request.getSession().removeAttribute("ToopherRequestToken"); - - try { - Map validatedData = iframeApi.validate(data, requestToken); - if (validatedData.containsKey("error_code")) { - // check for API errors - String errorCode = validatedData.get("error_code"); - if (errorCode.equals(ToopherIframe.PAIRING_DEACTIVATED)) { - // User deleted the pairing on their mobile device. - // - // Your server should display a Toopher Pairing iframe so their account can be re-paired - // - } else if (errorCode.equals(ToopherIframe.USER_OPT_OUT)) { - // User has been marked as "Opt-Out" in the Toopher API - // - // If your service allows opt-out, the user should be granted access. - // - } else if (errorCode.equals(ToopherIframe.USER_UNKNOWN)) { - // User has never authenticated with Toopher on this server - // - // Your server should display a Toopher Pairing iframe so their account can be paired - // - } - } else { - // Signature is valid, and no api errors -- check authentication result - boolean authPending = validatedData.get("pending").toLowerCase().equals("true"); - boolean authGranted = validatedData.get("granted").toLowerCase().equals("true"); - - // authenticationResult is the ultimate result of Toopher second-factor authentication - boolean authenticationResult = authGranted && !authPending; - if (authenticationResults) { - // Log user in - } else { - // Fail authentication attempt - } - } - } catch (ToopherIframe.SignatureValidationError e) { - // Signature was invalid -- user should not authenticated - // - // e.getMessage() will return more information about what specifically - // went wrong (incorrect session token, expired TTL, invalid signature) - // - } diff --git a/README.md b/README.md index f217cd1..e3259c0 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,19 @@ -#ToopherJava +#ToopherJava [![Build Status](https://travis-ci.org/toopher/toopher-java.png?branch=master)](https://travis-ci.org/toopher/toopher-java) -[![Build -Status](https://travis-ci.org/toopher/toopher-java.png?branch=master)](https://travis-ci.org/toopher/toopher-java) +ToopherJava is a Toopher API library that simplifies the task of interfacing with the Toopher API from Java code. This project wrangles all the dependency libraries and handles the required OAuth and JSON functionality so you can focus on just using the API. -#### Introduction -ToopherJava is a Toopher API library that simplifies the task of interfacing with the Toopher API from Java code. This project includes all the dependency libraries and handles the required OAuth and JSON functionality so you can focus on just using the API. +*Note: ToopherJava is not meant for use in Android.* -Note: ToopherJava is not meant for use in Android. +### Java Version +\>=5.0 -#### Learn the Toopher API -Make sure you visit (http://dev.toopher.com) to get acquainted with the Toopher API fundamentals. The documentation there will tell you the details about the operations this API wrapper library provides. +### Documentation +Make sure you visit [https://dev.toopher.com](https://dev.toopher.com) to get acquainted with the Toopher API fundamentals. The documentation there will tell you the details about the operations this API wrapper library provides. -#### OAuth Authentication +## ToopherApi Workflow -The first step to accessing the Toopher API is to sign up for an account at the development portal (http://dev.toopher.com) and create a "requester". When that process is complete, your requester is issued OAuth 1.0a credentials in the form of a consumer key and secret. Your key is used to identify your requester when Toopher interacts with your customers, and the secret is used to sign each request so that we know it is generated by you. This library properly formats each request with your credentials automatically. - -#### The Toopher Two-Step -Interacting with the Toopher web service involves two steps: pairing, and authenticating. - -##### Pair -Before you can enhance your website's actions with Toopher, your customers will need to pair their phone's Toopher app with your website. To do this, they generate a unique, nonsensical "pairing phrase" from within the app on their phone. You will need to prompt them for a pairing phrase as part of the Toopher enrollment process. Once you have a pairing phrase, just send it to the Toopher API along with your requester credentials and we'll return a pairing ID that you can use whenever you want to authenticate an action for that user. - -##### Authenticate -You have complete control over what actions you want to authenticate using Toopher (for example: logging in, changing account information, making a purchase, etc.). Just send us the user's pairing ID, a name for the terminal they're using, and a description of the action they're trying to perform and we'll make sure they actually want it to happen. - -#### Librarified -This library makes it super simple to do the Toopher two-step. Check it out: +### Step 1: Pair +Before you can enhance your website's actions with Toopher, your customers will need to pair their mobile device's Toopher app with your website. To do this, they generate a unique pairing phrase from within the app on their mobile device. You will need to prompt them for a pairing phrase as part of the Toopher enrollment process. Once you have a pairing phrase, just send it to the Toopher API along with their username and we'll return a pairing ID that you can use whenever you want to authenticate an action for that user. ```java import com.toopher.*; @@ -33,26 +21,84 @@ import com.toopher.*; // Create an API object using your credentials ToopherAPI api = new ToopherAPI("", ""); -// Step 1 - Pair with their phone's Toopher app -PairingStatus pairing = api.pair("pairing phrase", "username@yourservice.com"); +// Step 1 - Pair with their mobile device's Toopher app +Pairing pairing = api.pair("username@yourservice.com", "pairing phrase"); +``` + +### Step 2: Authenticate +You have complete control over what actions you want to authenticate using Toopher (logging in, changing account information, making a purchase, etc.). Just send us the username or pairing ID and we'll make sure they actually want it to happen. You can also choose to provide the following optional parameters: terminal name, requester specified ID and action name (*default: "Log in"*). + +```java +// Create an optional Map of extra parameters to provide to the API +Map extras = new HashMap(); +extras.put("terminalName", "terminal name"); +extras.put("requesterSpecifiedId", "requester specified ID"); +extras.put("actionName", "action name"); // Step 2 - Authenticate a log in -AuthenticationStatus auth = api.authenticate(pairing.id, "my computer"); +AuthenticationRequest authenticationRequest = api.authenticate("username@yourservice.com", extras); // Once they've responded you can then check the status -AuthenticationStatus status = api.getAuthenticationStatus(auth.id); +authenticationRequest.refreshFromServer(); if (status.pending == false && status.granted == true) { // Success! } ``` -#### Handling Errors +## ToopherIframe Workflow + +### Step 1: Embed a request in an IFRAME +1. Generate an authentication URL by providing a username. +2. Display a webpage to your user that embeds this URL within an `