Skip to content

Commit 289b6c8

Browse files
author
Karl Rieb
committed
Add support for optional OAuth 2 authorize query parameters in DbxWebAuth.
1 parent cba35c4 commit 289b6c8

File tree

14 files changed

+1042
-280
lines changed

14 files changed

+1042
-280
lines changed

ChangeLog.txt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Fix ExceptionInInitializationError caused by CertificateParsingException when using Java 6 JREs.
55
- Add support for OkHttp3.
66
- Add support for Google App Engine with new GoogleAppEngineRequestor.
7+
- Add support for require_role, force_reapprove, state, and disable_signup parameters in the OAuth 2 web-based authorization flow (DbxWebAuth).
78

89
2.0.4 (2016-05-31)
910
---------------------------------------------

build.gradle

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import org.gradle.internal.os.OperatingSystem;
2+
13
apply plugin: 'java'
24
apply plugin: 'osgi'
35
apply plugin: 'maven'
@@ -242,9 +244,15 @@ if (project.sourceCompatibility == JavaVersion.VERSION_1_6) {
242244

243245
logger.info("Setting JVM boot classpath to use ${jdkHome}")
244246
project.tasks.withType(JavaCompile) {
245-
options.bootClasspath = "${jdkHome}/jre/lib/rt.jar"
246-
options.bootClasspath += "${sep}${jdkHome}/jre/lib/jsse.jar"
247-
options.bootClasspath += "${sep}${jdkHome}/jre/lib/jce.jar"
247+
def jdkLibs = "${jdkHome}/jre/lib"
248+
def runtimeClasses = "rt.jar"
249+
if (OperatingSystem.current().isMacOsX()) {
250+
jdkLibs = "${jdkHome}/Classes"
251+
runtimeClasses = "classes.jar"
252+
}
253+
options.bootClasspath = "${jdkLibs}/${runtimeClasses}"
254+
options.bootClasspath += "${sep}${jdkLibs}/jsse.jar"
255+
options.bootClasspath += "${sep}${jdkLibs}/jce.jar"
248256
}
249257
}
250258
}

examples/authorize/src/main/java/com/dropbox/core/examples/authorize/Main.java

+8-7
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66
import com.dropbox.core.DbxException;
77
import com.dropbox.core.DbxRequestConfig;
88
import com.dropbox.core.DbxWebAuth;
9-
import com.dropbox.core.DbxWebAuthNoRedirect;
109
import com.dropbox.core.json.JsonReader;
1110

1211
import java.io.BufferedReader;
13-
import java.io.IOException;
1412
import java.io.InputStreamReader;
15-
import java.io.PrintStream;
13+
import java.io.IOException;
1614
import java.util.logging.Level;
1715
import java.util.logging.Logger;
1816

@@ -61,9 +59,12 @@ public static void main(String[] args) throws IOException {
6159

6260
// Run through Dropbox API authorization process
6361
DbxRequestConfig requestConfig = new DbxRequestConfig("examples-authorize");
64-
DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(requestConfig, appInfo);
62+
DbxWebAuth webAuth = new DbxWebAuth(requestConfig, appInfo);
63+
DbxWebAuth.Request webAuthRequest = DbxWebAuth.newRequestBuilder()
64+
.withNoRedirect()
65+
.build();
6566

66-
String authorizeUrl = webAuth.start();
67+
String authorizeUrl = webAuth.authorize(webAuthRequest);
6768
System.out.println("1. Go to " + authorizeUrl);
6869
System.out.println("2. Click \"Allow\" (you might have to log in first).");
6970
System.out.println("3. Copy the authorization code.");
@@ -77,9 +78,9 @@ public static void main(String[] args) throws IOException {
7778

7879
DbxAuthFinish authFinish;
7980
try {
80-
authFinish = webAuth.finish(code);
81+
authFinish = webAuth.finishFromCode(code);
8182
} catch (DbxException ex) {
82-
System.err.println("Error in DbxWebAuth.start: " + ex.getMessage());
83+
System.err.println("Error in DbxWebAuth.authorize: " + ex.getMessage());
8384
System.exit(1); return;
8485
}
8586

examples/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ subprojects {
3636
//
3737
// This is intended to be used by the ./run script and not through gradle directly
3838
task run(type: JavaExec) {
39+
standardInput = System.in
3940
classpath = sourceSets.main.runtimeClasspath
4041
main = "com.dropbox.core.examples.${project.name.replace('-','_')}.Main"
4142
ignoreExitValue true

examples/web-file-browser/src/main/java/com/dropbox/core/examples/web_file_browser/DropboxAuth.java

+31-32
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616
* Handles the endpoints related to authorizing this app with the Dropbox API
1717
* via OAuth 2.
1818
*/
19-
public class DropboxAuth
20-
{
19+
public class DropboxAuth {
2120
private final Common common;
2221

23-
public DropboxAuth(Common common)
24-
{
22+
public DropboxAuth(Common common) {
2523
this.common = common;
2624
}
2725

@@ -31,14 +29,18 @@ public DropboxAuth(Common common)
3129
// Start the process of getting a Dropbox API access token for the user's Dropbox account.
3230

3331
public void doStart(HttpServletRequest request, HttpServletResponse response)
34-
throws IOException, ServletException
35-
{
32+
throws IOException, ServletException {
3633
if (!common.checkPost(request, response)) return;
3734
User user = common.requireLoggedInUser(request, response);
3835
if (user == null) return;
3936

4037
// Start the authorization process with Dropbox.
41-
String authorizeUrl = getWebAuth(request).start();
38+
DbxWebAuth.Request authRequest = DbxWebAuth.newRequestBuilder()
39+
// After we redirect the user to the Dropbox website for authorization,
40+
// Dropbox will redirect them back here.
41+
.withRedirectUri(getRedirectUri(request), getSessionStore(request))
42+
.build();
43+
String authorizeUrl = getWebAuth(request).authorize(authRequest);
4244

4345
// Redirect the user to the Dropbox website so they can approve our application.
4446
// The Dropbox website will send them back to /dropbox-auth-finish when they're done.
@@ -55,8 +57,7 @@ public void doStart(HttpServletRequest request, HttpServletResponse response)
5557
// an HTTP POST.
5658

5759
public void doFinish(HttpServletRequest request, HttpServletResponse response)
58-
throws IOException, ServletException
59-
{
60+
throws IOException, ServletException {
6061
if (!common.checkGet(request, response)) return;
6162

6263
User user = common.requireLoggedInUser(request, response);
@@ -67,33 +68,31 @@ public void doFinish(HttpServletRequest request, HttpServletResponse response)
6768

6869
DbxAuthFinish authFinish;
6970
try {
70-
authFinish = getWebAuth(request).finish(request.getParameterMap());
71-
}
72-
catch (DbxWebAuth.BadRequestException e) {
71+
authFinish = getWebAuth(request).finishFromRedirect(
72+
getRedirectUri(request),
73+
getSessionStore(request),
74+
request.getParameterMap()
75+
);
76+
} catch (DbxWebAuth.BadRequestException e) {
7377
common.log.println("On /dropbox-auth-finish: Bad request: " + e.getMessage());
7478
response.sendError(400);
7579
return;
76-
}
77-
catch (DbxWebAuth.BadStateException e) {
80+
} catch (DbxWebAuth.BadStateException e) {
7881
// Send them back to the start of the auth flow.
7982
response.sendRedirect(common.getUrl(request, "/dropbox-auth-start"));
8083
return;
81-
}
82-
catch (DbxWebAuth.CsrfException e) {
84+
} catch (DbxWebAuth.CsrfException e) {
8385
common.log.println("On /dropbox-auth-finish: CSRF mismatch: " + e.getMessage());
8486
response.sendError(403);
8587
return;
86-
}
87-
catch (DbxWebAuth.NotApprovedException e) {
88+
} catch (DbxWebAuth.NotApprovedException e) {
8889
common.page(response, 200, "Not approved?", "Why not, bro?");
8990
return;
90-
}
91-
catch (DbxWebAuth.ProviderException e) {
91+
} catch (DbxWebAuth.ProviderException e) {
9292
common.log.println("On /dropbox-auth-finish: Auth failed: " + e.getMessage());
9393
response.sendError(503, "Error communicating with Dropbox.");
9494
return;
95-
}
96-
catch (DbxException e) {
95+
} catch (DbxException e) {
9796
common.log.println("On /dropbox-auth-finish: Error getting token: " + e);
9897
response.sendError(503, "Error communicating with Dropbox.");
9998
return;
@@ -112,8 +111,7 @@ public void doFinish(HttpServletRequest request, HttpServletResponse response)
112111
// -------------------------------------------------------------------------------------------
113112

114113
public void doUnlink(HttpServletRequest request, HttpServletResponse response)
115-
throws IOException, ServletException
116-
{
114+
throws IOException, ServletException {
117115
if (!common.checkPost(request, response)) return;
118116
User user = common.requireLoggedInUser(request, response);
119117
if (user == null) return;
@@ -127,17 +125,18 @@ public void doUnlink(HttpServletRequest request, HttpServletResponse response)
127125

128126
// -------------------------------------------------------------------------------------------
129127

130-
private DbxWebAuth getWebAuth(final HttpServletRequest request)
131-
{
132-
// After we redirect the user to the Dropbox website for authorization,
133-
// Dropbox will redirect them back here.
134-
String redirectUrl = common.getUrl(request, "/dropbox-auth-finish");
135-
128+
private DbxSessionStore getSessionStore(final HttpServletRequest request) {
136129
// Select a spot in the session for DbxWebAuth to store the CSRF token.
137130
HttpSession session = request.getSession(true);
138131
String sessionKey = "dropbox-auth-csrf-token";
139-
DbxSessionStore csrfTokenStore = new DbxStandardSessionStore(session, sessionKey);
132+
return new DbxStandardSessionStore(session, sessionKey);
133+
}
134+
135+
private DbxWebAuth getWebAuth(final HttpServletRequest request) {
136+
return new DbxWebAuth(common.getRequestConfig(request), common.dbxAppInfo);
137+
}
140138

141-
return new DbxWebAuth(common.getRequestConfig(request), common.dbxAppInfo, redirectUrl, csrfTokenStore);
139+
private String getRedirectUri(final HttpServletRequest request) {
140+
return common.getUrl(request, "/dropbox-auth-finish");
142141
}
143142
}

src/main/java/com/dropbox/core/DbxAuthFinish.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public DbxAuthFinish read(JsonParser parser) throws IOException, JsonReadExcepti
7676
String accessToken = null;
7777
String tokenType = null;
7878
String userId = null;
79+
String state = null;
7980

8081
while (parser.getCurrentToken() == JsonToken.FIELD_NAME) {
8182
String fieldName = parser.getCurrentName();
@@ -91,6 +92,9 @@ else if (fieldName.equals("access_token")) {
9192
else if (fieldName.equals("uid")) {
9293
userId = JsonReader.StringReader.readField(parser, fieldName, userId);
9394
}
95+
else if (fieldName.equals("state")) {
96+
state = JsonReader.StringReader.readField(parser, fieldName, state);
97+
}
9498
else {
9599
// Unknown field. Skip over it.
96100
JsonReader.skipValue(parser);
@@ -107,7 +111,7 @@ else if (fieldName.equals("uid")) {
107111
if (accessToken == null) throw new JsonReadException("missing field \"access_token\"", top);
108112
if (userId == null) throw new JsonReadException("missing field \"uid\"", top);
109113

110-
return new DbxAuthFinish(accessToken, userId, null);
114+
return new DbxAuthFinish(accessToken, userId, state);
111115
}
112116
};
113117

src/main/java/com/dropbox/core/DbxRequestUtil.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.concurrent.TimeUnit;
1313
import java.util.ArrayList;
1414
import java.util.List;
15+
import java.util.Map;
1516

1617
import com.dropbox.core.stone.StoneSerializer;
1718
import com.dropbox.core.http.HttpRequestor;
@@ -30,8 +31,7 @@ public final class DbxRequestUtil {
3031
public static String encodeUrlParam(String s) {
3132
try {
3233
return URLEncoder.encode(s, "UTF-8");
33-
}
34-
catch (UnsupportedEncodingException ex) {
34+
} catch (UnsupportedEncodingException ex) {
3535
throw mkAssert("UTF-8 should always be supported", ex);
3636
}
3737
}
@@ -43,6 +43,17 @@ public static String buildUrlWithParams(/*@Nullable*/String userLocale,
4343
return buildUri(host, path) + "?" + encodeUrlParams(userLocale, params);
4444
}
4545

46+
static String [] toParamsArray(Map<String, String> params) {
47+
String [] arr = new String[2 * params.size()];
48+
int i = 0;
49+
for (Map.Entry<String, String> entry : params.entrySet()) {
50+
arr[i] = entry.getKey();
51+
arr[i + 1] = entry.getValue();
52+
i += 2;
53+
}
54+
return arr;
55+
}
56+
4657
public static String buildUri(String host, String path) {
4758
try {
4859
return new URI("https", host, "/" + path, null).toASCIIString();

src/main/java/com/dropbox/core/DbxSessionStore.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
* {@link DbxStandardSessionStore}.
1212
* </pre>
1313
*/
14-
public interface DbxSessionStore
15-
{
14+
public interface DbxSessionStore {
1615
public /*@Nullable*/String get();
1716
public void set(String value);
1817
public void clear();

0 commit comments

Comments
 (0)