diff --git a/managed_vms/endpoints/README.md b/managed_vms/endpoints/README.md new file mode 100644 index 00000000000..429f50d9691 --- /dev/null +++ b/managed_vms/endpoints/README.md @@ -0,0 +1,8 @@ +# Google Cloud Endpoints on App Engine flexible environment +This sample demonstrates how to use Google Cloud Endpoints on Google App Engine Flexible Environment using Java. + +## Running locally + $ mvn jetty:run + +## Deploying + $ mvn gcloud:deploy diff --git a/managed_vms/endpoints/pom.xml b/managed_vms/endpoints/pom.xml new file mode 100644 index 00000000000..2e43b6307ef --- /dev/null +++ b/managed_vms/endpoints/pom.xml @@ -0,0 +1,68 @@ + + + + 4.0.0 + war + 1.0-SNAPSHOT + com.example.managedvms + managed-vms-endpoints + + + doc-samples + com.google.cloud + 1.0.0 + ../.. + + + + + javax.servlet + javax.servlet-api + 3.1.0 + jar + provided + + + + com.google.code.gson + gson + 2.6.2 + compile + + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + com.google.appengine + gcloud-maven-plugin + 2.0.9.111.v20160527 + + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + false + + + + org.apache.maven.plugins + 3.3 + maven-compiler-plugin + + 1.7 + 1.7 + + + + org.eclipse.jetty + jetty-maven-plugin + 9.3.8.v20160314 + + + + diff --git a/managed_vms/endpoints/src/main/appengine/Dockerfile b/managed_vms/endpoints/src/main/appengine/Dockerfile new file mode 100644 index 00000000000..62ccde6e3f4 --- /dev/null +++ b/managed_vms/endpoints/src/main/appengine/Dockerfile @@ -0,0 +1,3 @@ +FROM gcr.io/google_appengine/jetty9 + +ADD . /app diff --git a/managed_vms/endpoints/src/main/appengine/app.yaml b/managed_vms/endpoints/src/main/appengine/app.yaml new file mode 100644 index 00000000000..6d375d8db22 --- /dev/null +++ b/managed_vms/endpoints/src/main/appengine/app.yaml @@ -0,0 +1,13 @@ +runtime: custom +vm: true + +handlers: +- url: /.* + script: this field is required, but ignored + secure: always + +beta_settings: + # Enable Google Cloud Endpoints API management. + use_endpoints_api_management: true + # Specify the Swagger API specification. + endpoints_swagger_spec_file: swagger.yaml diff --git a/managed_vms/endpoints/src/main/appengine/swagger.yaml b/managed_vms/endpoints/src/main/appengine/swagger.yaml new file mode 100644 index 00000000000..71bac9ce62f --- /dev/null +++ b/managed_vms/endpoints/src/main/appengine/swagger.yaml @@ -0,0 +1,106 @@ +swagger: "2.0" +info: + description: "A simple Google Cloud Endpoints API example." + title: "Endpoints Example" + version: "1.0.0" +host: "YOUR-PROJECT-ID.appspot.com" +basePath: "/" +consumes: +- "application/json" +produces: +- "application/json" +schemes: +- "https" +paths: + "/echo": + post: + description: "Echo back a given message." + operationId: "echo" + produces: + - "application/json" + responses: + 200: + description: "Echo" + schema: + $ref: "#/definitions/echoMessage" + parameters: + - description: "Message to echo" + in: body + name: message + required: true + schema: + $ref: "#/definitions/echoMessage" + "/auth/info/googlejwt": + get: + description: "Returns the requests' authentication information." + operationId: "auth_info_google_jwt" + produces: + - "application/json" + responses: + 200: + description: "Authenication info." + schema: + $ref: "#/definitions/authInfoResponse" + x-security: + - google_jwt: + audiences: + # This must match the "aud" field in the JWT. You can add multiple + # audiences to accept JWTs from multiple clients. + - "echo.endpoints.sample.google.com" + "/auth/info/googleidtoken": + get: + description: "Returns the requests' authentication information." + operationId: "authInfoGoogleIdToken" + produces: + - "application/json" + responses: + 200: + description: "Authenication info." + schema: + $ref: "#/definitions/authInfoResponse" + x-security: + - google_id_token: + audiences: + # Your OAuth2 client's Client ID must be added here. You can add + # multiple client IDs to accept tokens from multiple clients. + - "YOUR-CLIENT-ID" +definitions: + echoMessage: + properties: + message: + type: "string" + authInfoResponse: + properties: + id: + type: "string" + email: + type: "string" +# This section requires all requests to any path to require an API key. +security: +- api_key: [] +securityDefinitions: + # This section configures basic authentication with an API key. + api_key: + type: "apiKey" + name: "key" + in: "query" + # This section configures authentication using Google API Service Accounts + # to sign a json web token. This is mostly used for server-to-server + # communication. + google_jwt: + authorizationUrl: "" + flow: "implicit" + type: "oauth2" + # This must match the 'iss' field in the JWT. + x-issuer: "jwt-client.endpoints.sample.google.com" + # Update this with your service account's email address. + x-jwks_uri: "https://www.googleapis.com/service_accounts/v1/jwk/YOUR-SERVICE-ACCOUNT-EMAIL" + # This section configures authentication using Google OAuth2 ID Tokens. + # ID Tokens can be obtained using OAuth2 clients, and can be used to access + # your API on behalf of a particular user. + google_id_token: + authorizationUrl: "" + flow: "implicit" + type: "oauth2" + x-issuer: "accounts.google.com" + x-jwks_uri: "https://www.googleapis.com/oauth2/v1/certs" diff --git a/managed_vms/endpoints/src/main/java/com/example/managedvms/endpoints/AuthInfoServlet.java b/managed_vms/endpoints/src/main/java/com/example/managedvms/endpoints/AuthInfoServlet.java new file mode 100644 index 00000000000..c5bc081040c --- /dev/null +++ b/managed_vms/endpoints/src/main/java/com/example/managedvms/endpoints/AuthInfoServlet.java @@ -0,0 +1,59 @@ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.example.managedvms.endpoints; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Base64; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +/** + * A servlet that returns authentication information. + * See swagger.yaml for authentication mechanisms (e.g. JWT tokens, Google ID token). + */ +@WebServlet("/auth/info/*") +public class AuthInfoServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String encodedInfo = req.getHeader("X-Endpoint-API-UserInfo"); + if (encodedInfo == null || encodedInfo == "") { + JsonObject anon = new JsonObject(); + anon.addProperty("id", "anonymous"); + new Gson().toJson(anon, resp.getWriter()); + return; + } + + try { + byte[] authInfo = Base64.getDecoder().decode(encodedInfo); + resp.getOutputStream().write(authInfo); + } catch (IllegalArgumentException iae) { + resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); + JsonObject error = new JsonObject(); + error.addProperty("code", HttpServletResponse.SC_BAD_REQUEST); + error.addProperty("message", "Could not decode auth info."); + new Gson().toJson(error, resp.getWriter()); + } + } +} diff --git a/managed_vms/endpoints/src/main/java/com/example/managedvms/endpoints/EchoServlet.java b/managed_vms/endpoints/src/main/java/com/example/managedvms/endpoints/EchoServlet.java new file mode 100644 index 00000000000..e54da65bd43 --- /dev/null +++ b/managed_vms/endpoints/src/main/java/com/example/managedvms/endpoints/EchoServlet.java @@ -0,0 +1,58 @@ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.example.managedvms.endpoints; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.stream.JsonReader; + +/** + * A servlet that echoes JSON message bodies. + */ +@WebServlet("/echo") +public class EchoServlet extends HttpServlet { + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + resp.addHeader("Content-Encoding", "application/json"); + + Object responseBody; + try { + JsonReader jsonReader = new JsonReader(req.getReader()); + responseBody = new Gson().fromJson(jsonReader, Map.class); + } catch (JsonParseException je) { + resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); + JsonObject error = new JsonObject(); + error.addProperty("code", HttpServletResponse.SC_BAD_REQUEST); + error.addProperty("message", "Body was not valid JSON."); + responseBody = error; + } + + new Gson().toJson(responseBody, resp.getWriter()); + } +}