-
Notifications
You must be signed in to change notification settings - Fork 442
/
DropboxAuth.java
142 lines (120 loc) · 6.01 KB
/
DropboxAuth.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.dropbox.core.examples.web_file_browser;
import com.dropbox.core.DbxAuthFinish;
import com.dropbox.core.DbxException;
import com.dropbox.core.DbxSessionStore;
import com.dropbox.core.DbxStandardSessionStore;
import com.dropbox.core.DbxWebAuth;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
/**
* Handles the endpoints related to authorizing this app with the Dropbox API
* via OAuth 2.
*/
public class DropboxAuth {
private final Common common;
public DropboxAuth(Common common) {
this.common = common;
}
// -------------------------------------------------------------------------------------------
// POST /dropbox-auth-start
// -------------------------------------------------------------------------------------------
// Start the process of getting a Dropbox API access token for the user's Dropbox account.
public void doStart(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
if (!common.checkPost(request, response)) return;
User user = common.requireLoggedInUser(request, response);
if (user == null) return;
// Start the authorization process with Dropbox.
DbxWebAuth.Request authRequest = DbxWebAuth.newRequestBuilder()
// After we redirect the user to the Dropbox website for authorization,
// Dropbox will redirect them back here.
.withRedirectUri(getRedirectUri(request), getSessionStore(request))
.build();
String authorizeUrl = getWebAuth(request).authorize(authRequest);
// Redirect the user to the Dropbox website so they can approve our application.
// The Dropbox website will send them back to /dropbox-auth-finish when they're done.
response.sendRedirect(authorizeUrl);
}
// -------------------------------------------------------------------------------------------
// GET /dropbox-auth-finish
// -------------------------------------------------------------------------------------------
// The Dropbox API authorization page will redirect the user's browser to this page.
//
// This is a GET (even though it modifies state) because we get here via a browser
// redirect (Dropbox redirects the user here). You can't do a browser redirect to
// an HTTP POST.
public void doFinish(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
if (!common.checkGet(request, response)) return;
User user = common.requireLoggedInUser(request, response);
if (user == null) {
common.pageSoftError(response, "Can't do /dropbox-auth-finish. Nobody is logged in.");
return;
}
DbxAuthFinish authFinish;
try {
authFinish = getWebAuth(request).finishFromRedirect(
getRedirectUri(request),
getSessionStore(request),
request.getParameterMap()
);
} catch (DbxWebAuth.BadRequestException e) {
common.log.println("On /dropbox-auth-finish: Bad request: " + e.getMessage());
response.sendError(400);
return;
} catch (DbxWebAuth.BadStateException e) {
// Send them back to the start of the auth flow.
response.sendRedirect(common.getUrl(request, "/dropbox-auth-start"));
return;
} catch (DbxWebAuth.CsrfException e) {
common.log.println("On /dropbox-auth-finish: CSRF mismatch: " + e.getMessage());
response.sendError(403);
return;
} catch (DbxWebAuth.NotApprovedException e) {
common.page(response, 200, "Not approved?", "Why not, bro?");
return;
} catch (DbxWebAuth.ProviderException e) {
common.log.println("On /dropbox-auth-finish: Auth failed: " + e.getMessage());
response.sendError(503, "Error communicating with Dropbox.");
return;
} catch (DbxException e) {
common.log.println("On /dropbox-auth-finish: Error getting token: " + e);
response.sendError(503, "Error communicating with Dropbox.");
return;
}
// We have an Dropbox API access token now. This is what will let us make Dropbox API
// calls. Save it in the database entry for the current user.
user.dropboxAccessToken = authFinish.getAccessToken();
common.saveUserDb();
response.sendRedirect("/");
}
// -------------------------------------------------------------------------------------------
// POST /dropbox-unlink
// -------------------------------------------------------------------------------------------
public void doUnlink(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
if (!common.checkPost(request, response)) return;
User user = common.requireLoggedInUser(request, response);
if (user == null) return;
// Remove the access token from the database.
user.dropboxAccessToken = null;
common.saveUserDb();
response.sendRedirect("/");
}
// -------------------------------------------------------------------------------------------
private DbxSessionStore getSessionStore(final HttpServletRequest request) {
// Select a spot in the session for DbxWebAuth to store the CSRF token.
HttpSession session = request.getSession(true);
String sessionKey = "dropbox-auth-csrf-token";
return new DbxStandardSessionStore(session, sessionKey);
}
private DbxWebAuth getWebAuth(final HttpServletRequest request) {
return new DbxWebAuth(common.getRequestConfig(request), common.dbxAppInfo);
}
private String getRedirectUri(final HttpServletRequest request) {
return common.getUrl(request, "/dropbox-auth-finish");
}
}