15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The "Hello world!" of the Chrome Web Store Licensing API, in Java. This 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * program logs the user in with OpenID, fetches their license state with OAuth, 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and prints one of these greetings as appropriate: 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. Hello *no* license! 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2. Hello *free trial* license! 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3. Hello *full* license! 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Brian Kennish <bkennish@chromium.org> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package com.example; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.*; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.net.*; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.HashSet; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import javax.servlet.http.*; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.google.appengine.api.users.*; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.google.appengine.repackaged.org.json.JSONObject; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import oauth.signpost.OAuthConsumer; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import oauth.signpost.basic.DefaultOAuthConsumer; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A Google App Engine servlet. */ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@SuppressWarnings("serial") 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class HelloLicenseServlet extends HttpServlet { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: The app ID from the Chrome Developer Dashboard. */ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public static final String APP_ID = "[INSERT APP ID HERE]"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: The token from the Chrome Developer Dashboard. */ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static final String TOKEN = "[INSERT TOKEN HERE]"; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: The token secret from the Chrome Developer Dashboard. */ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static final String TOKEN_SECRET = "[INSERT TOKEN SECRET HERE]"; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The license server URL, where %s are placeholders for app and 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * user IDs 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public static final String SERVER_URL = 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "https://www.googleapis.com/chromewebstore/v1/licenses/%s/%s"; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The consumer key. */ 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public static final String CONSUMER_KEY = "anonymous"; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The consumer secret. */ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public static final String CONSUMER_SECRET = CONSUMER_KEY; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handles "GET" requests. */ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void doGet(HttpServletRequest request, HttpServletResponse response) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throws IOException { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.setContentType("text/html; charset=UTF-8"); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UserService userService = UserServiceFactory.getUserService(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintWriter output = response.getWriter(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) String url = request.getRequestURI(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (userService.isUserLoggedIn()) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Provide a logout path. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) User user = userService.getCurrentUser(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.printf( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<strong>%s</strong> | <a href=\"%s\">Sign out</a><br><br>", 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user.getEmail(), 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) userService.createLogoutURL(url) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send a signed request for the user's license state. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthConsumer oauth = 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oauth.setTokenWithSecret(TOKEN, TOKEN_SECRET); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLConnection http = 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new URL( 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) String.format( 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SERVER_URL, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) APP_ID, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLEncoder.encode(user.getFederatedIdentity(), "UTF-8") 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ).openConnection(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oauth.sign(http); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http.connect(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert the response from the license server to a string. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedReader input = 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new BufferedReader(new InputStreamReader(http.getInputStream())); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) String file = ""; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (String line; (line = input.readLine()) != null; file += line); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.close(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the string as JSON and display the license state. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JSONObject json = new JSONObject(file); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.printf( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Hello <strong>%s</strong> license!", 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "YES".equals(json.get("result")) ? 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FULL".equals(json.get("accessLevel")) ? "full" : "free trial" : 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "no" 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch (Exception exception) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Dump any error. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.printf("Oops! <strong>%s</strong>", exception.getMessage()); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { // The user isn't logged in. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prompt for login. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.printf( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<a href=\"%s\">Sign in</a>", 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) userService.createLoginURL( 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) null, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "https://www.google.com/accounts/o8/id", 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new HashSet<String>() 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 118