Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit 68777c9

Browse files
Michal GajdosGerrit Code Review
authored andcommitted
Merge "J-251: "NPE in oauth2-client-google-webapp""
2 parents f186555 + b4d2aca commit 68777c9

File tree

6 files changed

+119
-46
lines changed

6 files changed

+119
-46
lines changed

examples/oauth2-client-google-webapp/README.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ <h1>OAuth 2 client Google sample
7272
<p>This example demonstrates how to build a simple web JAX-RS application that can utilize JAX-RS client to
7373
query data from Google API using OAuth2 for authentication and authorization. This sample works only
7474
with
75-
browser as user interaction is needed to authorize the application for accessing user's Google Tasks.
75+
browser as user interaction is needed to authorize the application for accessing user's open Google Tasks.
7676
</p>
7777

7878
<h2>Contents</h2>

examples/oauth2-client-google-webapp/src/main/java/org/glassfish/jersey/examples/oauth2/googleclient/entity/TaskBean.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040

4141
package org.glassfish.jersey.examples.oauth2.googleclient.entity;
4242

43+
import java.util.Calendar;
44+
4345
import javax.xml.bind.annotation.XmlAttribute;
4446
import javax.xml.bind.annotation.XmlRootElement;
4547

@@ -56,11 +58,22 @@ public class TaskBean {
5658
@XmlAttribute
5759
private String title;
5860

61+
@XmlAttribute
62+
private Calendar completed;
63+
5964
public String getTitle() {
6065
return title;
6166
}
6267

6368
public void setTitle(String title) {
6469
this.title = title;
6570
}
71+
72+
public Calendar getCompleted() {
73+
return completed;
74+
}
75+
76+
public void setCompleted(final Calendar completed) {
77+
this.completed = completed;
78+
}
6679
}

examples/oauth2-client-google-webapp/src/main/java/org/glassfish/jersey/examples/oauth2/googleclient/resource/MyApplication.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@
4040

4141
package org.glassfish.jersey.examples.oauth2.googleclient.resource;
4242

43+
import java.util.logging.Logger;
44+
4345
import javax.ws.rs.ApplicationPath;
4446

47+
import org.glassfish.jersey.filter.LoggingFilter;
4548
import org.glassfish.jersey.server.ResourceConfig;
4649
import org.glassfish.jersey.server.mvc.mustache.MustacheMvcFeature;
4750

@@ -60,6 +63,7 @@ public MyApplication() {
6063
register(MustacheMvcFeature.class);
6164
property(MustacheMvcFeature.TEMPLATE_BASE_PATH, "/mustache");
6265

66+
register(new LoggingFilter(Logger.getLogger("example.server"), true));
6367
}
6468

6569
}

examples/oauth2-client-google-webapp/src/main/java/org/glassfish/jersey/examples/oauth2/googleclient/resource/SetupResource.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ public Response setup(@QueryParam("clientId") String consumerKey,
7070
@QueryParam("clientSecret") String consumerSecret) {
7171

7272
SimpleOAuthService.setClientIdentifier(new ClientIdentifier(consumerKey, consumerSecret));
73-
final URI uri = UriBuilder.fromUri(uriInfo.getBaseUri()).path("tasks")
74-
.build();
73+
final URI uri = UriBuilder.fromUri(uriInfo.getBaseUri()).path("tasks").build();
7574

7675
return Response.seeOther(uri).build();
7776
}

examples/oauth2-client-google-webapp/src/main/java/org/glassfish/jersey/examples/oauth2/googleclient/resource/TaskResource.java

Lines changed: 77 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,23 @@
4040

4141
package org.glassfish.jersey.examples.oauth2.googleclient.resource;
4242

43+
import java.net.URI;
4344
import java.util.ArrayList;
4445
import java.util.List;
46+
import java.util.logging.Logger;
4547

4648
import javax.ws.rs.GET;
4749
import javax.ws.rs.Path;
4850
import javax.ws.rs.Produces;
4951
import javax.ws.rs.client.Client;
5052
import javax.ws.rs.client.WebTarget;
5153
import javax.ws.rs.core.Context;
52-
import javax.ws.rs.core.MediaType;
5354
import javax.ws.rs.core.Response;
5455
import javax.ws.rs.core.UriBuilder;
5556
import javax.ws.rs.core.UriInfo;
5657

58+
import javax.servlet.ServletContext;
59+
5760
import org.glassfish.jersey.client.oauth2.OAuth2ClientSupport;
5861
import org.glassfish.jersey.client.oauth2.OAuth2CodeGrantFlow;
5962
import org.glassfish.jersey.client.oauth2.OAuth2FlowGoogleBuilder;
@@ -64,6 +67,7 @@
6467
import org.glassfish.jersey.examples.oauth2.googleclient.model.AllTaskListsModel;
6568
import org.glassfish.jersey.examples.oauth2.googleclient.model.TaskListModel;
6669
import org.glassfish.jersey.examples.oauth2.googleclient.model.TaskModel;
70+
import org.glassfish.jersey.filter.LoggingFilter;
6771
import org.glassfish.jersey.jackson.JacksonFeature;
6872
import org.glassfish.jersey.server.mvc.Template;
6973

@@ -74,66 +78,109 @@
7478
*/
7579
@Path("tasks")
7680
public class TaskResource {
81+
7782
private static final String GOOGLE_TASKS_BASE_URI = "https://www.googleapis.com/tasks/v1/";
83+
7884
@Context
7985
private UriInfo uriInfo;
86+
@Context
87+
private ServletContext servletContext;
8088

8189
@GET
8290
@Template(name = "/tasks.mustache")
8391
@Produces("text/html")
8492
public Response getTasks() {
93+
// check oauth setup
94+
if (SimpleOAuthService.getClientIdentifier() == null) {
95+
final URI uri = UriBuilder.fromUri(servletContext.getContextPath())
96+
.path("/index.html") //to show "Enter your Client Id and Secret" setup page
97+
.build();
98+
return Response.seeOther(uri).build();
99+
}
100+
// check access token
85101
if (SimpleOAuthService.getAccessToken() == null) {
86-
final String redirectURI = UriBuilder.fromUri(uriInfo.getBaseUri())
87-
.path("oauth2/authorize").build().toString();
88-
89-
final OAuth2CodeGrantFlow flow = OAuth2ClientSupport.googleFlowBuilder(
90-
SimpleOAuthService.getClientIdentifier(),
91-
redirectURI,
92-
"https://www.googleapis.com/auth/tasks.readonly")
93-
.prompt(OAuth2FlowGoogleBuilder.Prompt.CONSENT).build();
94-
95-
SimpleOAuthService.setFlow(flow);
96-
97-
// start the flow
98-
final String googleAuthURI = flow.start();
99-
100-
// redirect user to Google Authorization URI.
101-
return Response.seeOther(UriBuilder.fromUri(googleAuthURI).build()).build();
102+
return googleAuthRedirect();
102103
}
103104
// We have already an access token. Query the data from Google API.
104105
final Client client = SimpleOAuthService.getFlow().getAuthorizedClient();
105-
final AllTaskListsModel allTaskListsModel = getTasks(client);
106-
return Response.ok(allTaskListsModel).type(MediaType.TEXT_HTML_TYPE).build();
106+
return getTasksResponse(client);
107107
}
108108

109+
/**
110+
* Prepare redirect response to Google Tasks API auth consent request.
111+
*
112+
* @return redirect response to Google Tasks API auth consent request
113+
*/
114+
private Response googleAuthRedirect() {
115+
final String redirectURI = UriBuilder.fromUri(uriInfo.getBaseUri())
116+
.path("oauth2/authorize").build().toString();
117+
118+
final OAuth2CodeGrantFlow flow = OAuth2ClientSupport.googleFlowBuilder(
119+
SimpleOAuthService.getClientIdentifier(),
120+
redirectURI,
121+
"https://www.googleapis.com/auth/tasks.readonly")
122+
.prompt(OAuth2FlowGoogleBuilder.Prompt.CONSENT).build();
123+
124+
SimpleOAuthService.setFlow(flow);
125+
126+
// start the flow
127+
final String googleAuthURI = flow.start();
128+
129+
// redirect user to Google Authorization URI.
130+
return Response.seeOther(UriBuilder.fromUri(googleAuthURI).build()).build();
131+
}
109132

110133
/**
111134
* Queries task data from google.
135+
*
112136
* @param client Client configured for authentication with access token.
113-
* @return String html Google task data.
137+
* @return Google task data response or redirect to google authorize page response.
114138
*/
115-
private static AllTaskListsModel getTasks(final Client client) {
139+
private Response getTasksResponse(final Client client) {
116140
client.register(JacksonFeature.class);
141+
client.register(new LoggingFilter(Logger.getLogger("example.client.tasks"), true));
142+
117143
final WebTarget baseTarget = client.target(GOOGLE_TASKS_BASE_URI);
118144
final Response response = baseTarget.path("users/@me/lists").request().get();
119145

120-
final TaskRootBean taskRootBean = response.readEntity(TaskRootBean.class);
146+
final List<TaskListModel> listOfTaskLists;
147+
switch (response.getStatus()) {
148+
case 401: //Response.Status.UNAUTHORIZED
149+
SimpleOAuthService.setAccessToken(null);
150+
return googleAuthRedirect();
151+
case 200: //Response.Status.OK
152+
listOfTaskLists = processTaskLists(baseTarget, response.readEntity(TaskRootBean.class));
153+
break;
154+
default:
155+
listOfTaskLists = null;
156+
}
157+
158+
final AllTaskListsModel tasks = new AllTaskListsModel(listOfTaskLists);
159+
return Response.ok(tasks).build();
160+
}
121161

122-
final List<TaskListModel> listOfTaskLists = new ArrayList<TaskListModel>();
162+
/**
163+
* Process users task lists and read task details. Collect just
164+
* @param baseTarget base JAX-RS client target with oauth context configured
165+
* @param taskRootBean root task bean to be processed
166+
* @return Detailed list of non-completed tasks or {@code null} if there is no task list available.
167+
*/
168+
private List<TaskListModel> processTaskLists(final WebTarget baseTarget, final TaskRootBean taskRootBean) {
169+
final List<TaskListModel> listOfTaskLists = new ArrayList<>();
123170
for (final TaskListBean taskListBean : taskRootBean.getItems()) {
124-
final List<TaskModel> taskList = new ArrayList<TaskModel>();
171+
final List<TaskModel> taskList = new ArrayList<>();
125172
final WebTarget listTarget = baseTarget.path("lists/{tasklist}/tasks")
126173
.resolveTemplate("tasklist", taskListBean.getId());
127174

128175
final TaskListBean fullTaskListBean = listTarget.request().get(TaskListBean.class);
129176
for (final TaskBean taskBean : fullTaskListBean.getTasks()) {
130-
taskList.add(new TaskModel(taskBean.getTitle()));
177+
if (taskBean.getCompleted() == null) {
178+
taskList.add(new TaskModel(taskBean.getTitle()));
179+
}
131180
}
132-
final TaskListModel listModel = new TaskListModel(taskListBean == null ? "No tasks were found. Define some tasks."
133-
: taskListBean.getTitle(), taskList);
134-
listOfTaskLists.add(listModel);
135-
181+
listOfTaskLists.add(new TaskListModel(taskListBean.getTitle(), taskList.size() > 0 ? taskList : null));
136182
}
137-
return new AllTaskListsModel(listOfTaskLists);
183+
return listOfTaskLists.size() > 0 ? listOfTaskLists : null;
138184
}
185+
139186
}

examples/oauth2-client-google-webapp/src/main/resources/mustache/tasks.mustache

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
44
5-
Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
5+
Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
66
77
The contents of this file are subject to the terms of either the GNU
88
General Public License Version 2 only ("GPL") or the Common Development
@@ -56,20 +56,30 @@
5656
<div class="row">
5757
<div class="col-lg-offset-2 col-lg-8">
5858
<header class="page-header">
59-
<h1>Tasks</h1>
59+
<h1>Open Tasks</h1>
6060
</header>
61-
{{#taskListModels}}
62-
<div class="panel panel-default">
63-
<div class="panel-heading">
64-
<h3 class="panel-title">{{title}}</h3>
65-
</div>
66-
{{#tasks}}
67-
<div class="panel-body">
68-
{{title}}
61+
{{#taskListModels}}
62+
<div class="panel panel-default">
63+
<div class="panel-heading">
64+
<h3 class="panel-title">{{title}}</h3>
6965
</div>
70-
{{/tasks}}
71-
</div>
72-
{{/taskListModels}}
66+
{{#tasks}}
67+
<div class="panel-body">
68+
{{title}}
69+
</div>
70+
{{/tasks}}
71+
{{^tasks}}
72+
<div class="panel-body alert alert-warning">
73+
No open tasks were found. Define some tasks.
74+
</div>
75+
{{/tasks}}
76+
</div>
77+
{{/taskListModels}}
78+
{{^taskListModels}}
79+
<div class="panel-heading alert alert-warning">
80+
No task list were found. Create some list.
81+
</div>
82+
{{/taskListModels}}
7383
</div>
7484
</div>
7585
</div>

0 commit comments

Comments
 (0)