From 02d025bd85f1cd23f5316bc7fb3464be4302178c Mon Sep 17 00:00:00 2001 From: Baskaran D Date: Mon, 25 Feb 2013 20:19:07 -0800 Subject: [PATCH 01/12] Fix OAuth 2.0 AccessToken flow for the GrantType: authrozation_code. Included RefreshToken flow also --- sample-proxies/oauth-authcode/README.md | 18 ++-- .../apiproxy/policies/CheckQuota.xml | 9 -- .../apiproxy/policies/ClassifyRequest.xml | 9 -- .../apiproxy/policies/GenerateAccessToken.xml | 2 +- .../apiproxy/policies/RefreshAccessToken.xml | 7 ++ .../apiproxy/policies/ValidateOAuth.xml | 6 -- .../apiproxy/proxies/default.xml | 17 ++-- sample-proxies/oauth-authcode/deploy.sh | 0 sample-proxies/oauth-authcode/invoke.sh | 82 +++++++++++++------ 9 files changed, 76 insertions(+), 74 deletions(-) delete mode 100644 sample-proxies/oauth-authcode/apiproxy/policies/CheckQuota.xml delete mode 100644 sample-proxies/oauth-authcode/apiproxy/policies/ClassifyRequest.xml create mode 100644 sample-proxies/oauth-authcode/apiproxy/policies/RefreshAccessToken.xml delete mode 100644 sample-proxies/oauth-authcode/apiproxy/policies/ValidateOAuth.xml mode change 100644 => 100755 sample-proxies/oauth-authcode/deploy.sh mode change 100644 => 100755 sample-proxies/oauth-authcode/invoke.sh diff --git a/sample-proxies/oauth-authcode/README.md b/sample-proxies/oauth-authcode/README.md index 4ae62458..7e013068 100644 --- a/sample-proxies/oauth-authcode/README.md +++ b/sample-proxies/oauth-authcode/README.md @@ -2,22 +2,14 @@ This sample shows how use the OAuth 2.0 "authorization code" grant type, which redirects the end user to a login page, then once the user is authenticated, it returns -an access token. - -It also validates incoming requests using the -access token, and uses an API Product to assign a quota value to each application, and -enforces that quota. +an access token. Also, shows how to refresh the accesstoken once it got expired. It contains the following policies: -1. An AssignMessage policy to set the "flow.resource.name" variable. -2. An OAuth 2.0 policy to generate the authorization code that is required in order to -authenticate a user. -3. An OAuth 2.0 policy to generate the access token on a specific URL. -4. An OAuth 2.0 policy to validate the access token for another URL, and to look -up attributes from the API Product associated with the application. -5. A policy to enforce a quota on the number of API calls based on the values set -in the API Product. +1. An OAuth 2.0 AuthorizationCode policy to generate the authorization code on a specific URL, called Authorization Endpoint + This authorization code is is required in order to authenticate a user. +2. An OAuth 2.0 AccessToken policy to generate the access token on a specific URL, called AccessToken Endpoint +3. An OAuth 2.0 RefreshToken policy to generate new access token on a specific URL, called RefreshToken Endpoint # Set up diff --git a/sample-proxies/oauth-authcode/apiproxy/policies/CheckQuota.xml b/sample-proxies/oauth-authcode/apiproxy/policies/CheckQuota.xml deleted file mode 100644 index 701b1057..00000000 --- a/sample-proxies/oauth-authcode/apiproxy/policies/CheckQuota.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/sample-proxies/oauth-authcode/apiproxy/policies/ClassifyRequest.xml b/sample-proxies/oauth-authcode/apiproxy/policies/ClassifyRequest.xml deleted file mode 100644 index 4c5afab9..00000000 --- a/sample-proxies/oauth-authcode/apiproxy/policies/ClassifyRequest.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - flow.resource.name - proxy.pathsuffix - - diff --git a/sample-proxies/oauth-authcode/apiproxy/policies/GenerateAccessToken.xml b/sample-proxies/oauth-authcode/apiproxy/policies/GenerateAccessToken.xml index fcd9371b..2c5080ae 100644 --- a/sample-proxies/oauth-authcode/apiproxy/policies/GenerateAccessToken.xml +++ b/sample-proxies/oauth-authcode/apiproxy/policies/GenerateAccessToken.xml @@ -9,6 +9,6 @@ type because it allows a client to get access to a token with no user authentication --> authorization_code - request.queryparam.grant_type + request.queryparam.grant_type diff --git a/sample-proxies/oauth-authcode/apiproxy/policies/RefreshAccessToken.xml b/sample-proxies/oauth-authcode/apiproxy/policies/RefreshAccessToken.xml new file mode 100644 index 00000000..8cd3ea50 --- /dev/null +++ b/sample-proxies/oauth-authcode/apiproxy/policies/RefreshAccessToken.xml @@ -0,0 +1,7 @@ + + RefreshAccessToken + + 1800000 + request.queryparam.grant_type + + diff --git a/sample-proxies/oauth-authcode/apiproxy/policies/ValidateOAuth.xml b/sample-proxies/oauth-authcode/apiproxy/policies/ValidateOAuth.xml deleted file mode 100644 index d96f667a..00000000 --- a/sample-proxies/oauth-authcode/apiproxy/policies/ValidateOAuth.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - VerifyAccessToken - - diff --git a/sample-proxies/oauth-authcode/apiproxy/proxies/default.xml b/sample-proxies/oauth-authcode/apiproxy/proxies/default.xml index 911fa226..1a5bd923 100644 --- a/sample-proxies/oauth-authcode/apiproxy/proxies/default.xml +++ b/sample-proxies/oauth-authcode/apiproxy/proxies/default.xml @@ -1,4 +1,5 @@ + @@ -7,6 +8,7 @@ GenerateAuthCode + proxy.pathsuffix == "/oauth/accesstoken" @@ -15,11 +17,11 @@ - - + + + proxy.pathsuffix == "/oauth/refresh_accesstoken" - ValidateOAuth - CheckQuota + RefreshAccessToken @@ -30,8 +32,5 @@ secure - - - default - - \ No newline at end of file + + diff --git a/sample-proxies/oauth-authcode/deploy.sh b/sample-proxies/oauth-authcode/deploy.sh old mode 100644 new mode 100755 diff --git a/sample-proxies/oauth-authcode/invoke.sh b/sample-proxies/oauth-authcode/invoke.sh old mode 100644 new mode 100755 index dcee1fcd..5035ad17 --- a/sample-proxies/oauth-authcode/invoke.sh +++ b/sample-proxies/oauth-authcode/invoke.sh @@ -1,21 +1,5 @@ #!/bin/bash -rawurlencode() { - local string="${1}" - local strlen=${#string} - local encoded="" - - for (( pos=0 ; pos/dev/null`; callback=`echo "$appdata" | grep callbackUrl | awk -F '\"' '{ print $4 }'`; consumerkey=`echo "$appdata" | grep -m 1 consumerKey | awk -F '\"' '{ print $4 }'`; consumersecret=`echo "$appdata" | grep -m 1 consumerSecret | awk -F '\"' '{ print $4 }'`; -echo "Fetching redirect URL" -sleep 1 -redirect_headers=`curl -k --head "https://$org-$env.$api_domain/weatheroauthauthcode/oauth/authorize?response_type=code&client_id=$consumerkey&redirect_uri=$callback&scope=READ&state=foobar" 2>/dev/null` -sleep 1 + +###### Authozation Code Flow Begins here...... + +authorization_request="https://$org-$env.$api_domain/weatheroauthauthcode/oauth/authorize?response_type=code&client_id=$consumerkey&redirect_uri=$callback&scope=READ&state=foobar" + +echo -e "\nCalling Authorization Endpoint to get authorization code: \n" +echo -e "curl -k $authorization_request \n" + +echo -e "Fetching redirect URL\n" +redirect_headers=`curl -k --head "$authorization_request" 2>/dev/null` + redirect_url=`echo "$redirect_headers" | grep "Location: " | sed -e 's/^Location: //' -e 's/[ \t\n\r]\$//g'` -echo "The app would now redirect to $redirect_url" -echo "We will now simulate what would happen when authentication succeeded there." +echo -e "The app would now redirect to $callback" +echo -e "We will now simulate what would happen when authentication succeeded there.\n" qsparams=`echo "$redirect_url" | awk -F "?" '{ print $2 }' | sed -e 's:&: :g'`; for qsparam in $qsparams; do @@ -49,7 +40,44 @@ for qsparam in $qsparams; do fi done -token_request_url="https://$org-$env.$api_domain/weatheroauthauthcode/oauth/accesstoken?grant_type=authorization_code&code=${authcode}&redirect_uri=$( rawurlencode $redirect_url )&scope=READ" -echo "Calling $token_request_url" -tokenoutput=`curl -k -u "$consumerkey:$consumersecret" "$token_request_url" 2>/dev/null` -echo "$tokenoutput" +###### AccessToken Flow Begins here...... + +accesstoken_request="https://$org-$env.$api_domain/weatheroauthauthcode/oauth/accesstoken?grant_type=authorization_code" + +echo -e "\nCalling AccessToken Endpoint to get access token\n" + +echo -e "curl -k -u $consumerkey:$consumersecret $accesstoken_request -X POST -d \"code=${authcode}&redirect_uri=$callback&scope=READ\" -H \"Content-type: application/x-www-form-urlencoded\" \n\n" + +accesstoken_response=`curl -k -u $consumerkey:$consumersecret $accesstoken_request -X POST -d "code=${authcode}&redirect_uri=$callback&scope=READ" -H "Content-type: application/x-www-form-urlencoded" 2>/dev/null` + +echo -e "AccessToken Response \n $accesstoken_response \n" + +#Extracting AccessToken & RefreshToken +access_token=`echo $accesstoken_response | awk -F "," '{ print $10 }' | awk -F ":" '{print $2}' | sed -e 's/[^a-zA-Z0-9]//g'` +refresh_token=`echo $accesstoken_response | awk -F "," '{ print $9 }' | awk -F ":" '{print $2}' | sed -e 's/[^a-zA-Z0-9]//g'` + +echo -e "AccessToken: $access_token" +echo -e "RefreshToken: $refresh_token \n" + + +###### RefreshToken Begins here...... + +echo -e "\nNow assume that the accesstoken got expired." +echo -e "It can be refreshed by calling to the refresh token endpoint, with the help of refreshtoken provided for the accesstoken\n" + +refreshtoken_request="https://$org-$env.$api_domain/weatheroauthauthcode/oauth/refresh_accesstoken?grant_type=refresh_token" + +echo -e "Calling RefreshToken Endpoint to get new access token\n" + +echo -e "curl -k -u $consumerkey:$consumersecret $refreshtoken_request -X POST -d \"refresh_token=${refresh_token}\" -H \"Content-type: application/x-www-form-urlencoded\" \n\n" + +new_accesstoken_response=`curl -k -u $consumerkey:$consumersecret $refreshtoken_request -X POST -d "refresh_token=${refresh_token}" -H "Content-type: application/x-www-form-urlencoded" 2>/dev/null` + +echo -e "New AccessToken Response \n $new_accesstoken_response \n" + +#Extracting AccessToken & RefreshToken +new_access_token=`echo $new_accesstoken_response | awk -F "," '{ print $9 }' | awk -F ":" '{print $2}' | sed -e 's/[^a-zA-Z0-9]//g'` +new_refresh_token=`echo $new_accesstoken_response | awk -F "," '{ print $8 }' | awk -F ":" '{print $2}' | sed -e 's/[^a-zA-Z0-9]//g'` + +echo -e "New AccessToken: $new_access_token" +echo -e "New RefreshToken: $new_refresh_token \n\n" From 7b29544cc11e14487db21f9139b74cd215ca47ac Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 15:33:22 -0500 Subject: [PATCH 02/12] updated with proxy generation script instructions --- tools/README.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/README.md b/tools/README.md index 5633c726..78a02837 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,4 +1,29 @@ -# Python Deploy Tool for the Apigee API Platform +# Apigee Platform Samples Tooles + +This directory contains two tools: + +# API Proxy Generator + +Requires curl to be installed. + +A simple script that uses the Apigee API Platform API to generate an API proxy. The +script downloads the API proxy generated by the API Platform, enabling you +to customize it locally. + +Use the Python Deploy Tool to import and deploy your API proxy as you iterate +during development. + +Run: + +$ sh proxy_gen.sh + +Follow prompts. + +The API proxy will be downloaded and unzipped to a directory called /apiproxy. + +# API Proxy Deploy Tool + +Requires Python to be installed. This tool provides a simple command for importing and deploying an API proxy from your local machine to an environment on the Apigee API Platform. From 7aae787d839fa0e355c068dd5ad579faf4561468 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 15:34:26 -0500 Subject: [PATCH 03/12] fixed name in script --- sample-proxies/simple-javascript/deploy.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sample-proxies/simple-javascript/deploy.sh diff --git a/sample-proxies/simple-javascript/deploy.sh b/sample-proxies/simple-javascript/deploy.sh new file mode 100644 index 00000000..5a2c0f0a --- /dev/null +++ b/sample-proxies/simple-javascript/deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +echo Deploying $proxy to $env on $url using $username and $org + +../../tools/deploy.py -n simple-javascript -u $username:$password -o $org -h $url -e $env -p / -d ../simple-javascript + +echo "If 'State: deployed', then your API Proxy is ready to be invoked." + +echo "Run 'invoke.sh'" From dd0ec2511253eed31b5531fa1eed6ab328a03385 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 15:40:43 -0500 Subject: [PATCH 04/12] modified policy type --- simpleProxy/apiproxy/policies/ValidateAPIKey.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleProxy/apiproxy/policies/ValidateAPIKey.xml b/simpleProxy/apiproxy/policies/ValidateAPIKey.xml index f4d526ee..d40d813f 100644 --- a/simpleProxy/apiproxy/policies/ValidateAPIKey.xml +++ b/simpleProxy/apiproxy/policies/ValidateAPIKey.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file From 9cc7955b14ecc083ee59bf1ceb00b592a99a97b3 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 15:51:24 -0500 Subject: [PATCH 05/12] modified resource types to JSC (compiled JavaScript), a backwards compatible change--all JavaScript resources should now use .jsc extensions and resource type. --- .../apiproxy/policies/javascriptpolicy.xml | 2 +- .../simple-javascript/apiproxy/proxies/proxy.xml | 2 +- .../simple-javascript/apiproxy/resources/js/setHeader.js | 8 -------- 3 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 sample-proxies/simple-javascript/apiproxy/resources/js/setHeader.js diff --git a/sample-proxies/simple-javascript/apiproxy/policies/javascriptpolicy.xml b/sample-proxies/simple-javascript/apiproxy/policies/javascriptpolicy.xml index 43eac4f4..25bbf751 100644 --- a/sample-proxies/simple-javascript/apiproxy/policies/javascriptpolicy.xml +++ b/sample-proxies/simple-javascript/apiproxy/policies/javascriptpolicy.xml @@ -1,3 +1,3 @@ diff --git a/sample-proxies/simple-javascript/apiproxy/proxies/proxy.xml b/sample-proxies/simple-javascript/apiproxy/proxies/proxy.xml index 6fd466aa..3242fbe1 100644 --- a/sample-proxies/simple-javascript/apiproxy/proxies/proxy.xml +++ b/sample-proxies/simple-javascript/apiproxy/proxies/proxy.xml @@ -11,4 +11,4 @@ twitter - + \ No newline at end of file diff --git a/sample-proxies/simple-javascript/apiproxy/resources/js/setHeader.js b/sample-proxies/simple-javascript/apiproxy/resources/js/setHeader.js deleted file mode 100644 index 48ee2142..00000000 --- a/sample-proxies/simple-javascript/apiproxy/resources/js/setHeader.js +++ /dev/null @@ -1,8 +0,0 @@ -response.setVariable("header.X-Apigee-Demo-Target", flow.getVariable("target.name")); -response.setVariable("header.X-Apigee-Demo-ApiProxyName", flow.getVariable("apiproxy.name")); -response.setVariable("header.X-Apigee-Demo-ProxyName", flow.getVariable("proxy.name")); -response.setVariable("header.X-Apigee-Demo-ProxyBasePath", flow.getVariable("proxy.basepath")); -response.setVariable("header.X-Apigee-Demo-ProxyPathSuffix", flow.getVariable("proxy.pathsuffix")); -response.setVariable("header.X-Apigee-Demo-ProxyUrl", flow.getVariable("proxy.url")); - - From 984d7aea106d18d46a1ffed85a028e82c3b28992 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 15:52:30 -0500 Subject: [PATCH 06/12] modified resource types to JSC (compiled JavaScript), a backwards compatible change--all JavaScript resources should now use .jsc extensions and resource type. --- .../apiproxy/policies/MashItUp.xml | 2 +- .../apiproxy/resources/jsc/MashItUp.js | 67 ------------------- sample-proxies/javascript-mashup/deploy.sh | 15 +++++ 3 files changed, 16 insertions(+), 68 deletions(-) delete mode 100644 sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.js create mode 100644 sample-proxies/javascript-mashup/deploy.sh diff --git a/sample-proxies/javascript-mashup/apiproxy/policies/MashItUp.xml b/sample-proxies/javascript-mashup/apiproxy/policies/MashItUp.xml index 246e477a..79331f28 100644 --- a/sample-proxies/javascript-mashup/apiproxy/policies/MashItUp.xml +++ b/sample-proxies/javascript-mashup/apiproxy/policies/MashItUp.xml @@ -1,3 +1,3 @@ - jsc://MashItUp.js + jsc://MashItUp.jsc diff --git a/sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.js b/sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.js deleted file mode 100644 index 3a2f363f..00000000 --- a/sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.js +++ /dev/null @@ -1,67 +0,0 @@ -// Initialize the response that might already be hanging around -response.content = ''; -response.headers['Content-Type'] = 'application/json'; - -try { - if ((request.queryParams.postalcode == undefined) || - (request.queryParams.country == undefined)) { - throw '"postalcode" and "country" query parameters are required'; - } - - // Send an HTTP GET to the URL that we construct - var geocoding = httpClient.get( - 'http://maps.googleapis.com/maps/api/geocode/json?address=' + - request.queryParams.postalcode + - '®ion=' + request.queryParams.country + - '&sensor=false'); - geocoding.waitForComplete(); - if (!geocoding.isSuccess()) { - throw 'Error contacting geocoding web service'; - } - // We got a response. Parse the JSON into a JavaScript object. - geocodeResponse = geocoding.getResponse().content.asJSON; - if (geocodeResponse.status != 'OK') { - throw 'Error returned from geocoding web service: ' + geocodeResponse.status; - } - - // Go through the JavaScript returned by Google and get the results - var lat = geocodeResponse.results[0].geometry.location.lat; - var lng = geocodeResponse.results[0].geometry.location.lng; - - // Send another HTTP GET to the other service - var altitude = httpClient.get( - 'http://maps.googleapis.com/maps/api/elevation/json?sensor=false&locations=' + - lat + ',' + lng); - altitude.waitForComplete(); - if (!altitude.isSuccess()) { - throw 'Error contacting altitude web service'; - } - altitudeResponse = altitude.getResponse().content.asJSON; - if (altitudeResponse.status != 'OK') { - throw 'Error returned from altitude web service: ' + altitudeResponse.status; - } - - var alt = altitudeResponse.results[0].elevation; - - // Assemble the parts of the response as a JavaScript object - var location = new Object(); - location.latitude = lat; - location.longitude = lng; - - var altitude = new Object(); - altitude.meters = alt; - altitude.feet = alt * 3.2808399; - - // Final assembly, then turn it into a JSON object - var body = response.content.asJSON; - body.country = request.queryParams.country; - body.postalcode = request.queryParams.postalcode; - body.elevation = location; - body.altitude = altitude; - -} catch (err) { - // Handle any error that may have happened previously by generating a response - response.content.asJSON.error = err; -} - - diff --git a/sample-proxies/javascript-mashup/deploy.sh b/sample-proxies/javascript-mashup/deploy.sh new file mode 100644 index 00000000..551f8ebe --- /dev/null +++ b/sample-proxies/javascript-mashup/deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +echo Deploying $proxy to $env on $url using $username and $org + +../../tools/deploy.py -n javascript-mashup -u $username:$password -o $org -h $url -e $env -p / -d ../javascript-mashup + +echo "If 'State: deployed', then your API Proxy is ready to be invoked." + +echo "Run 'invoke.sh'" \ No newline at end of file From 7f44822758421f6af8c27a1484a0206d2d7d7073 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 15:53:21 -0500 Subject: [PATCH 07/12] clarified instrucions --- sample-proxies/apikey/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-proxies/apikey/README.md b/sample-proxies/apikey/README.md index 5fb5ed65..c7dcda08 100644 --- a/sample-proxies/apikey/README.md +++ b/sample-proxies/apikey/README.md @@ -24,7 +24,7 @@ Update /setup/setenv.sh with your environment details Run: -/setup/deploy.sh +$ sh deploy.sh Testing From e99c4afa6f92016ff5358f87773b360522b72d69 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 16:31:18 -0500 Subject: [PATCH 08/12] added local deploy script --- sample-proxies/apikey/deploy.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sample-proxies/apikey/deploy.sh diff --git a/sample-proxies/apikey/deploy.sh b/sample-proxies/apikey/deploy.sh new file mode 100644 index 00000000..2a5db238 --- /dev/null +++ b/sample-proxies/apikey/deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +echo Deploying $proxy to $env on $url using $username and $org + +../../tools/deploy.py -n apikey -u $username:$password -o $org -h $url -e $env -p / -d ../apikey + +echo "If 'State: deployed', then your API Proxy is ready to be invoked." + +echo "Run 'invoke.sh'" \ No newline at end of file From 617cbc60d24c4b9e23fc271a71e2a4e5eb18d482 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 16:31:40 -0500 Subject: [PATCH 09/12] added local deploy script --- sample-proxies/conditional-policy/deploy.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sample-proxies/conditional-policy/deploy.sh diff --git a/sample-proxies/conditional-policy/deploy.sh b/sample-proxies/conditional-policy/deploy.sh new file mode 100644 index 00000000..e05e1dd8 --- /dev/null +++ b/sample-proxies/conditional-policy/deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +echo Deploying $proxy to $env on $url using $username and $org + +../../tools/deploy.py -n conditional-policy -u $username:$password -o $org -h $url -e $env -p / -d ../conditional-policy + +echo "If 'State: deployed', then your API Proxy is ready to be invoked." + +echo "Run 'invoke.sh'" \ No newline at end of file From 8c64edd93a16c23e77674f0a9c76eed7fdc6dfb8 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 16:32:02 -0500 Subject: [PATCH 10/12] added local deploy script --- sample-proxies/policy-mashup/deploy.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sample-proxies/policy-mashup/deploy.sh diff --git a/sample-proxies/policy-mashup/deploy.sh b/sample-proxies/policy-mashup/deploy.sh new file mode 100644 index 00000000..7e9728d1 --- /dev/null +++ b/sample-proxies/policy-mashup/deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +echo Deploying $proxy to $env on $url using $username and $org + +../../tools/deploy.py -n policy-mashup -u $username:$password -o $org -h $url -e $env -p / -d ../policy-mashup + +echo "If 'State: deployed', then your API Proxy is ready to be invoked." + +echo "Run 'invoke.sh'" \ No newline at end of file From a778c307c48a8e97de832c5d85fa6e08aab9e86c Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Feb 2013 16:36:05 -0500 Subject: [PATCH 11/12] Updated Javascript samples to use JSC resource type (for compiled Javascript) and moced twitter-translate policies to the proper location --- .../apiproxy/resources/jsc/MashItUp.jsc | 67 +++++++++++++++++++ .../apiproxy/resources/jsc/setHeader.jsc | 6 ++ .../apiproxy/policies/policies/cors.xml | 5 -- .../{policies => }/timeline-translate.xml | 0 4 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.jsc create mode 100644 sample-proxies/simple-javascript/apiproxy/resources/jsc/setHeader.jsc delete mode 100644 sample-proxies/twitter-translate/apiproxy/policies/policies/cors.xml rename sample-proxies/twitter-translate/apiproxy/policies/{policies => }/timeline-translate.xml (100%) diff --git a/sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.jsc b/sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.jsc new file mode 100644 index 00000000..3a2f363f --- /dev/null +++ b/sample-proxies/javascript-mashup/apiproxy/resources/jsc/MashItUp.jsc @@ -0,0 +1,67 @@ +// Initialize the response that might already be hanging around +response.content = ''; +response.headers['Content-Type'] = 'application/json'; + +try { + if ((request.queryParams.postalcode == undefined) || + (request.queryParams.country == undefined)) { + throw '"postalcode" and "country" query parameters are required'; + } + + // Send an HTTP GET to the URL that we construct + var geocoding = httpClient.get( + 'http://maps.googleapis.com/maps/api/geocode/json?address=' + + request.queryParams.postalcode + + '®ion=' + request.queryParams.country + + '&sensor=false'); + geocoding.waitForComplete(); + if (!geocoding.isSuccess()) { + throw 'Error contacting geocoding web service'; + } + // We got a response. Parse the JSON into a JavaScript object. + geocodeResponse = geocoding.getResponse().content.asJSON; + if (geocodeResponse.status != 'OK') { + throw 'Error returned from geocoding web service: ' + geocodeResponse.status; + } + + // Go through the JavaScript returned by Google and get the results + var lat = geocodeResponse.results[0].geometry.location.lat; + var lng = geocodeResponse.results[0].geometry.location.lng; + + // Send another HTTP GET to the other service + var altitude = httpClient.get( + 'http://maps.googleapis.com/maps/api/elevation/json?sensor=false&locations=' + + lat + ',' + lng); + altitude.waitForComplete(); + if (!altitude.isSuccess()) { + throw 'Error contacting altitude web service'; + } + altitudeResponse = altitude.getResponse().content.asJSON; + if (altitudeResponse.status != 'OK') { + throw 'Error returned from altitude web service: ' + altitudeResponse.status; + } + + var alt = altitudeResponse.results[0].elevation; + + // Assemble the parts of the response as a JavaScript object + var location = new Object(); + location.latitude = lat; + location.longitude = lng; + + var altitude = new Object(); + altitude.meters = alt; + altitude.feet = alt * 3.2808399; + + // Final assembly, then turn it into a JSON object + var body = response.content.asJSON; + body.country = request.queryParams.country; + body.postalcode = request.queryParams.postalcode; + body.elevation = location; + body.altitude = altitude; + +} catch (err) { + // Handle any error that may have happened previously by generating a response + response.content.asJSON.error = err; +} + + diff --git a/sample-proxies/simple-javascript/apiproxy/resources/jsc/setHeader.jsc b/sample-proxies/simple-javascript/apiproxy/resources/jsc/setHeader.jsc new file mode 100644 index 00000000..f2574bdb --- /dev/null +++ b/sample-proxies/simple-javascript/apiproxy/resources/jsc/setHeader.jsc @@ -0,0 +1,6 @@ +response.setVariable("header.X-Apigee-Demo-Target", flow.getVariable("target.name")); +response.setVariable("header.X-Apigee-Demo-ApiProxyName", flow.getVariable("apiproxy.name")); +response.setVariable("header.X-Apigee-Demo-ProxyName", flow.getVariable("proxy.name")); +response.setVariable("header.X-Apigee-Demo-ProxyBasePath", flow.getVariable("proxy.basepath")); +response.setVariable("header.X-Apigee-Demo-ProxyPathSuffix", flow.getVariable("proxy.pathsuffix")); +response.setVariable("header.X-Apigee-Demo-ProxyUrl", flow.getVariable("proxy.url")); \ No newline at end of file diff --git a/sample-proxies/twitter-translate/apiproxy/policies/policies/cors.xml b/sample-proxies/twitter-translate/apiproxy/policies/policies/cors.xml deleted file mode 100644 index cd0ab874..00000000 --- a/sample-proxies/twitter-translate/apiproxy/policies/policies/cors.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - jsc://cors - diff --git a/sample-proxies/twitter-translate/apiproxy/policies/policies/timeline-translate.xml b/sample-proxies/twitter-translate/apiproxy/policies/timeline-translate.xml similarity index 100% rename from sample-proxies/twitter-translate/apiproxy/policies/policies/timeline-translate.xml rename to sample-proxies/twitter-translate/apiproxy/policies/timeline-translate.xml From b6374b3b5a4853a1eb917a3ab810c0011dea6e31 Mon Sep 17 00:00:00 2001 From: Baskaran D Date: Tue, 26 Feb 2013 17:16:02 -0800 Subject: [PATCH 12/12] Add sample bundle for OAuth20 Verify AccessToken flow to access a protected resource --- .../oauth-verify-accesstoken/README.md | 63 ++++++++++++++++++ .../apiproxy/OAuthVerifyTokenSample.xml | 3 + .../apiproxy/policies/CheckQuota.xml | 9 +++ .../apiproxy/policies/ValidateOAuth.xml | 6 ++ .../apiproxy/proxies/default.xml | 22 +++++++ .../apiproxy/targets/default.xml | 6 ++ .../oauth-verify-accesstoken/deploy.sh | 15 +++++ .../oauth-verify-accesstoken/invoke.sh | 64 +++++++++++++++++++ setup/provisioning/joe-app-product.xml | 2 +- 9 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 sample-proxies/oauth-verify-accesstoken/README.md create mode 100644 sample-proxies/oauth-verify-accesstoken/apiproxy/OAuthVerifyTokenSample.xml create mode 100644 sample-proxies/oauth-verify-accesstoken/apiproxy/policies/CheckQuota.xml create mode 100644 sample-proxies/oauth-verify-accesstoken/apiproxy/policies/ValidateOAuth.xml create mode 100644 sample-proxies/oauth-verify-accesstoken/apiproxy/proxies/default.xml create mode 100644 sample-proxies/oauth-verify-accesstoken/apiproxy/targets/default.xml create mode 100755 sample-proxies/oauth-verify-accesstoken/deploy.sh create mode 100755 sample-proxies/oauth-verify-accesstoken/invoke.sh diff --git a/sample-proxies/oauth-verify-accesstoken/README.md b/sample-proxies/oauth-verify-accesstoken/README.md new file mode 100644 index 00000000..8cbe24a3 --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/README.md @@ -0,0 +1,63 @@ +# Three-Legged OAuth + +This sample shows how use the OAuth 2.0 AccessToken is used to access a protected resource. +It also validates incoming requests using the access token, and +uses an API Product to assign a quota value to each client and enforces that quota. + +It contains the following policies: + +1. An OAuth 2.0 policy to validate the access token for the request URL, and to look +up attributes from the API Product associated with the application. +2. A policy to enforce a quota on the number of API calls based on the values set +in the API Product. + +# Note + +As, this flow involves Generation of AccessToken before requesting the protected resource, +the "invoke.sh" will guide you through the Generation of AccessToken flow, +before proceeding with the Verification + + +# Set up + +* The username and password that you use to login to enterprise.apigee.com. +* The name of the organization in which you have an account. Login to + enterprise.apigee.com and check account settings. + +# Configure + +Update /setup/setenv.sh with your environment details + +Configure API products, developers, and apps in your organization: + +Run: + +/setup/provisioning/setup.sh + +# Import and deploy sample project + +Run: + +/setup/deploy.sh + +Testing + +$ sh invoke.sh + +# Get help + +For assistance, post to http://support.apigee.com + +Copyright 2013 Apigee Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy +of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/sample-proxies/oauth-verify-accesstoken/apiproxy/OAuthVerifyTokenSample.xml b/sample-proxies/oauth-verify-accesstoken/apiproxy/OAuthVerifyTokenSample.xml new file mode 100644 index 00000000..1d9527b1 --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/apiproxy/OAuthVerifyTokenSample.xml @@ -0,0 +1,3 @@ + + A sample API proxy that enforces OAuth 2.0 Auth Code + diff --git a/sample-proxies/oauth-verify-accesstoken/apiproxy/policies/CheckQuota.xml b/sample-proxies/oauth-verify-accesstoken/apiproxy/policies/CheckQuota.xml new file mode 100644 index 00000000..9e1cd2f8 --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/apiproxy/policies/CheckQuota.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/sample-proxies/oauth-verify-accesstoken/apiproxy/policies/ValidateOAuth.xml b/sample-proxies/oauth-verify-accesstoken/apiproxy/policies/ValidateOAuth.xml new file mode 100644 index 00000000..d96f667a --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/apiproxy/policies/ValidateOAuth.xml @@ -0,0 +1,6 @@ + + + VerifyAccessToken + + diff --git a/sample-proxies/oauth-verify-accesstoken/apiproxy/proxies/default.xml b/sample-proxies/oauth-verify-accesstoken/apiproxy/proxies/default.xml new file mode 100644 index 00000000..667b438f --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/apiproxy/proxies/default.xml @@ -0,0 +1,22 @@ + + + + + + ValidateOAuth + CheckQuota + + + + + + + /weather + + secure + + + + default + + diff --git a/sample-proxies/oauth-verify-accesstoken/apiproxy/targets/default.xml b/sample-proxies/oauth-verify-accesstoken/apiproxy/targets/default.xml new file mode 100644 index 00000000..add74713 --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/apiproxy/targets/default.xml @@ -0,0 +1,6 @@ + + + + http://weather.yahooapis.com/ + + \ No newline at end of file diff --git a/sample-proxies/oauth-verify-accesstoken/deploy.sh b/sample-proxies/oauth-verify-accesstoken/deploy.sh new file mode 100755 index 00000000..1e4499c8 --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +echo Deploying $proxy to $env on $url using $username and $org + +../../tools/deploy.py -n oauth-verify-accesstoken -u $username:$password -o $org -h $url -e $env -p / -d ../oauth-verify-accesstoken + +echo "If 'State: deployed', then your API Proxy is ready to be invoked." + +echo "Run 'invoke.sh'" diff --git a/sample-proxies/oauth-verify-accesstoken/invoke.sh b/sample-proxies/oauth-verify-accesstoken/invoke.sh new file mode 100755 index 00000000..231bc515 --- /dev/null +++ b/sample-proxies/oauth-verify-accesstoken/invoke.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +echo "Using org and environment configured in /setup/setenv.sh" +echo "Be sure to run scripts under ./setup/provisioning" + +source ../../setup/setenv.sh + +echo -e "\nDefine AccessToken grant_type:( authorization_code/[client_credentials] ):" +read grant_type + +if [ -z $grant_type ]; then + echo -e "Grant_Type defaults to 'client_credentials'. \n" + grant_type="client_credentials" +fi + +echo -e "Is the Proxy for the grant_type: $grant_type already deployed? ( [yes]/no ):" +read deploy_status + +if [ "$deploy_status" != "no" ]; then + deploy_status="yes" +fi + +if [ "$grant_type" == "authorization_code" ]; then + echo -e "Deploying proxy for Grant_Type: authorization_code \n" + if [ $deploy_status != "yes" ]; then + /bin/bash ../oauth-auth*/deploy.sh + fi + /bin/bash ../oauth-auth*/invoke.sh +else + echo -e "Deploying proxy for Grant_Type: client_credentials \n" + if [ $deploy_status != "yes" ]; then + /bin/bash ../oauth-client*/deploy.sh + fi + /bin/bash ../oauth-client*/invoke.sh +fi + +echo -e "\nAccessToken has be generated. Now we can access the protected resource with the above generated AccessToken" + +echo -e "\nPass a valid AccessToken to verify it: [Hint: Steal the above shown Accesstoken!] " +read access_token + + +echo -e "\nRequesting the Protected Resource with AccessToken\n" + +echo -e "curl -k https://$org-$env.$api_domain/weather/forecastrss?w=12797282 -H 'Authorization: Bearer $access_token' \n" + +curl -k https://$org-$env.$api_domain/weather/forecastrss?w=12797282 -H "Authorization: Bearer $access_token" + + +echo -e "\nRequesting the Protected Resource with Invalid AccessToken\n" + +echo -e "curl -k https://$org-$env.$api_domain/weather/forecastrss?w=12797282 -H 'Authorization: Bearer XYZ_INVALID_ACCESTOKEN_XYZ' \n" + +curl -k https://$org-$env.$api_domain/weather/forecastrss?w=12797282 -H "Authorization: Bearer XYZ_INVALID_ACCESTOKEN_XYZ" + +echo -e "\n\n" + +echo -e "###################### TRY YOURSELF! ######################\n" +echo -e "Fire the below request multiple times in a minute, to see Ratelimiting getting implemented\n" + +echo -e "curl -k https://$org-$env.$api_domain/weather/forecastrss?w=12797282 -H 'Authorization: Bearer $access_token' \n" +echo -e "###################### TRY YOURSELF! ######################\n" + +echo -e "\n\n" diff --git a/setup/provisioning/joe-app-product.xml b/setup/provisioning/joe-app-product.xml index 4a849a90..2dd31551 100644 --- a/setup/provisioning/joe-app-product.xml +++ b/setup/provisioning/joe-app-product.xml @@ -1,5 +1,5 @@ - ExpensiveProduct + FreeProduct