如何使用 Dropbox Java/Android SDK v2 自动授权?
How to auth automatically with Dropbox Java/Android SDK v2?
为了提高应用质量,我正在进行测试:单元测试和 UI 测试。因为我在应用程序中支持 Dropbox 我想测试它并且我需要在测试之前授权 Dropbox 帐户(在我的 android 应用程序中用户能够保存文件,阅读它们,重命名, etc - 基本文件例程)。
Dropbox 提供 Java/Android SDK v2 with examples but even command-line tool 需要一些手动操作 - 使用 URL 和 select 帐户打开浏览器应用程序:
// Run through Dropbox API authorization process
DbxRequestConfig requestConfig = new DbxRequestConfig("examples-authorize");
DbxWebAuth webAuth = new DbxWebAuth(requestConfig, appInfo);
DbxWebAuth.Request webAuthRequest = DbxWebAuth.newRequestBuilder()
.withNoRedirect()
.build();
String authorizeUrl = webAuth.authorize(webAuthRequest);
System.out.println("1. Go to " + authorizeUrl);
System.out.println("2. Click \"Allow\" (you might have to log in first).");
System.out.println("3. Copy the authorization code.");
System.out.print("Enter the authorization code here: ");
String code = new BufferedReader(new InputStreamReader(System.in)).readLine();
if (code == null) {
System.exit(1); return;
}
code = code.trim();
DbxAuthFinish authFinish;
try {
authFinish = webAuth.finishFromCode(code);
} catch (DbxException ex) {
System.err.println("Error in DbxWebAuth.authorize: " + ex.getMessage());
System.exit(1); return;
}
System.out.println("Authorization complete.");
System.out.println("- User ID: " + authFinish.getUserId());
System.out.println("- Access Token: " + authFinish.getAccessToken());
是否可以让 Dropbox 自动验证而无需手动交互?我希望为会话提供应用程序 key/secret、帐户 email/password 并获得 accessToken
。
PS。我想避免使用 Robelectric+Espresso 并将其保留在 unit/integration 测试中,而不是 UI 测试中。
不,Dropbox API 不提供自动化应用程序授权流程的方法。
请注意,尽管您可以存储和重复使用访问令牌,因此您可能只想为您的测试帐户手动获取一次,然后再使用它。
这是我的测试模板(希望对大家有帮助)。
您必须至少手动进行 TODO
和 运行 两次测试(以粘贴授权代码和访问令牌),然后才能进行测试。接下来的所有测试调用都不需要手动执行任何操作。
public class DropboxFileSystemTest {
// credentials
private static final String APP_KEY = ""; // TODO : paste your app key
private static final String APP_SECRET = ""; // TODO : paste your app secret
// do run the test and follow the instructions
private static final String accountEmail = "test@domain.com"; // TODO : paste your test Dropbox account
private static String authCode; // TODO : run the test and paste auth code
private static String accessToken // TODO : run the test and paste access
private DbxAppInfo appInfo = new DbxAppInfo(APP_KEY, APP_SECRET);
// Run through Dropbox API authorization process
private DbxRequestConfig requestConfig = new DbxRequestConfig(DropboxFileSystemTest.class.getSimpleName());
private DbxWebAuth webAuth = new DbxWebAuth(requestConfig, appInfo);
private void startAuth() throws IOException {
DbxWebAuth.Request webAuthRequest = DbxWebAuth.newRequestBuilder()
.withNoRedirect()
.build();
String authorizeUrl = webAuth.authorize(webAuthRequest);
System.out.println("1. Go to " + authorizeUrl);
System.out.println("2. Click \"Allow\" (you might have to log in first). WARNING: log-in to " + accountEmail);
System.out.println("3. Copy the authorization code.");
System.out.println("4. Paste the authorization code to this test `this.authCode` value");
System.out.println("5. Re-run the test");
}
private DbxClientV2 client; // to be used for the requests
private void initWithAccessToken() {
DbxRequestConfig config = new DbxRequestConfig(UUID.randomUUID().toString());
client = new DbxClientV2(config, accessToken);
}
private void initAndVerifyAccount() throws DbxException {
initWithAccessToken();
// check expected account (trying to prevent user account to be wiped out)
DbxClientV2 client = DbxClientHolder.get().getClient();
FullAccount account = client.users().getCurrentAccount();
if (!account.getEmail().equals(accountEmail))
throw new RuntimeException("Wrong account: current is " + account.getEmail() + ", but " + accountEmail + " is expected");
}
private void clearFileSystem() throws FileSystemException {
// TODO : clear Dropbox file system
}
@Before
public void setUp() throws IOException, FileSystemException, DbxException {
auth();
clearFileSystem();
}
private void finishAuth() {
DbxAuthFinish authFinish;
try {
authFinish = webAuth.finishFromCode(authCode);
} catch (DbxException ex) {
System.err.println("Error in DbxWebAuth.authorize: " + ex.getMessage());
System.exit(1); return;
}
System.out.println("Authorization complete.");
System.out.println("- User ID: " + authFinish.getUserId());
System.out.println("- Access Token: " + authFinish.getAccessToken());
System.out.println();
System.out.println("1. Copy the access token");
System.out.println("2. Paste the access token to this test `this.accessToken` value");
System.out.println("3. Re-run the test");
accessToken = authFinish.getAccessToken();
}
private void auth() throws IOException, FileSystemException, DbxException {
if (accessToken == null) {
if (authCode != null ) {
finishAuth();
throw new RuntimeException("Manual actions required: copy-paste access token");
} else {
startAuth();
throw new RuntimeException("Manual actions required: copy-paste authCode");
}
} else {
initAndVerifyAccount();
}
}
@After
public void tearDown() throws FileSystemException {
if (client != null) {
clearFileSystem();
}
}
@Test
public void testSmth() {
// TODO : write your test using `this.client` for requests
}
为了提高应用质量,我正在进行测试:单元测试和 UI 测试。因为我在应用程序中支持 Dropbox 我想测试它并且我需要在测试之前授权 Dropbox 帐户(在我的 android 应用程序中用户能够保存文件,阅读它们,重命名, etc - 基本文件例程)。
Dropbox 提供 Java/Android SDK v2 with examples but even command-line tool 需要一些手动操作 - 使用 URL 和 select 帐户打开浏览器应用程序:
// Run through Dropbox API authorization process
DbxRequestConfig requestConfig = new DbxRequestConfig("examples-authorize");
DbxWebAuth webAuth = new DbxWebAuth(requestConfig, appInfo);
DbxWebAuth.Request webAuthRequest = DbxWebAuth.newRequestBuilder()
.withNoRedirect()
.build();
String authorizeUrl = webAuth.authorize(webAuthRequest);
System.out.println("1. Go to " + authorizeUrl);
System.out.println("2. Click \"Allow\" (you might have to log in first).");
System.out.println("3. Copy the authorization code.");
System.out.print("Enter the authorization code here: ");
String code = new BufferedReader(new InputStreamReader(System.in)).readLine();
if (code == null) {
System.exit(1); return;
}
code = code.trim();
DbxAuthFinish authFinish;
try {
authFinish = webAuth.finishFromCode(code);
} catch (DbxException ex) {
System.err.println("Error in DbxWebAuth.authorize: " + ex.getMessage());
System.exit(1); return;
}
System.out.println("Authorization complete.");
System.out.println("- User ID: " + authFinish.getUserId());
System.out.println("- Access Token: " + authFinish.getAccessToken());
是否可以让 Dropbox 自动验证而无需手动交互?我希望为会话提供应用程序 key/secret、帐户 email/password 并获得 accessToken
。
PS。我想避免使用 Robelectric+Espresso 并将其保留在 unit/integration 测试中,而不是 UI 测试中。
不,Dropbox API 不提供自动化应用程序授权流程的方法。
请注意,尽管您可以存储和重复使用访问令牌,因此您可能只想为您的测试帐户手动获取一次,然后再使用它。
这是我的测试模板(希望对大家有帮助)。
您必须至少手动进行 TODO
和 运行 两次测试(以粘贴授权代码和访问令牌),然后才能进行测试。接下来的所有测试调用都不需要手动执行任何操作。
public class DropboxFileSystemTest {
// credentials
private static final String APP_KEY = ""; // TODO : paste your app key
private static final String APP_SECRET = ""; // TODO : paste your app secret
// do run the test and follow the instructions
private static final String accountEmail = "test@domain.com"; // TODO : paste your test Dropbox account
private static String authCode; // TODO : run the test and paste auth code
private static String accessToken // TODO : run the test and paste access
private DbxAppInfo appInfo = new DbxAppInfo(APP_KEY, APP_SECRET);
// Run through Dropbox API authorization process
private DbxRequestConfig requestConfig = new DbxRequestConfig(DropboxFileSystemTest.class.getSimpleName());
private DbxWebAuth webAuth = new DbxWebAuth(requestConfig, appInfo);
private void startAuth() throws IOException {
DbxWebAuth.Request webAuthRequest = DbxWebAuth.newRequestBuilder()
.withNoRedirect()
.build();
String authorizeUrl = webAuth.authorize(webAuthRequest);
System.out.println("1. Go to " + authorizeUrl);
System.out.println("2. Click \"Allow\" (you might have to log in first). WARNING: log-in to " + accountEmail);
System.out.println("3. Copy the authorization code.");
System.out.println("4. Paste the authorization code to this test `this.authCode` value");
System.out.println("5. Re-run the test");
}
private DbxClientV2 client; // to be used for the requests
private void initWithAccessToken() {
DbxRequestConfig config = new DbxRequestConfig(UUID.randomUUID().toString());
client = new DbxClientV2(config, accessToken);
}
private void initAndVerifyAccount() throws DbxException {
initWithAccessToken();
// check expected account (trying to prevent user account to be wiped out)
DbxClientV2 client = DbxClientHolder.get().getClient();
FullAccount account = client.users().getCurrentAccount();
if (!account.getEmail().equals(accountEmail))
throw new RuntimeException("Wrong account: current is " + account.getEmail() + ", but " + accountEmail + " is expected");
}
private void clearFileSystem() throws FileSystemException {
// TODO : clear Dropbox file system
}
@Before
public void setUp() throws IOException, FileSystemException, DbxException {
auth();
clearFileSystem();
}
private void finishAuth() {
DbxAuthFinish authFinish;
try {
authFinish = webAuth.finishFromCode(authCode);
} catch (DbxException ex) {
System.err.println("Error in DbxWebAuth.authorize: " + ex.getMessage());
System.exit(1); return;
}
System.out.println("Authorization complete.");
System.out.println("- User ID: " + authFinish.getUserId());
System.out.println("- Access Token: " + authFinish.getAccessToken());
System.out.println();
System.out.println("1. Copy the access token");
System.out.println("2. Paste the access token to this test `this.accessToken` value");
System.out.println("3. Re-run the test");
accessToken = authFinish.getAccessToken();
}
private void auth() throws IOException, FileSystemException, DbxException {
if (accessToken == null) {
if (authCode != null ) {
finishAuth();
throw new RuntimeException("Manual actions required: copy-paste access token");
} else {
startAuth();
throw new RuntimeException("Manual actions required: copy-paste authCode");
}
} else {
initAndVerifyAccount();
}
}
@After
public void tearDown() throws FileSystemException {
if (client != null) {
clearFileSystem();
}
}
@Test
public void testSmth() {
// TODO : write your test using `this.client` for requests
}