Skip to content

Commit

Permalink
Add OAuth support
Browse files Browse the repository at this point in the history
Closes issue #75 and issue #184
  • Loading branch information
TrevorBasinger authored and kevinsawicki committed Oct 5, 2012
1 parent ba9d173 commit 13c6a7e
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 8 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ gen-external-apklibs
.idea
*.iml
.DS_Store
*.swp
3 changes: 2 additions & 1 deletion app/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />

<supports-screens
Expand Down Expand Up @@ -338,4 +339,4 @@
android:exported="false" />
</application>

</manifest>
</manifest>
3 changes: 3 additions & 0 deletions app/src/main/java/com/github/mobile/GitHubModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
import org.eclipse.egit.github.core.service.IssueService;
import org.eclipse.egit.github.core.service.PullRequestService;

import static com.github.mobile.accounts.AccountConstants.ACCOUNT_NAME;
import static com.github.mobile.accounts.AccountConstants.APP_URL;

/**
* Main module provide services and clients
*/
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/github/mobile/ServicesModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.egit.github.core.service.LabelService;
import org.eclipse.egit.github.core.service.MilestoneService;
import org.eclipse.egit.github.core.service.OrganizationService;
import org.eclipse.egit.github.core.service.OAuthService;
import org.eclipse.egit.github.core.service.PullRequestService;
import org.eclipse.egit.github.core.service.RepositoryService;
import org.eclipse.egit.github.core.service.UserService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,34 @@
import static android.accounts.AccountManager.KEY_BOOLEAN_RESULT;
import static android.accounts.AccountManager.KEY_INTENT;
import static com.github.mobile.accounts.AccountConstants.ACCOUNT_TYPE;
import static com.github.mobile.accounts.AccountConstants.ACCOUNT_NAME;
import static com.github.mobile.accounts.AccountConstants.APP_URL;
import static com.github.mobile.accounts.LoginActivity.PARAM_AUTHTOKEN_TYPE;
import static com.github.mobile.accounts.LoginActivity.PARAM_USERNAME;
import com.github.mobile.DefaultClient;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.NetworkErrorException;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import org.eclipse.egit.github.core.service.OAuthService;
import org.eclipse.egit.github.core.Authorization;

import java.lang.Thread;
import java.util.List;

class AccountAuthenticator extends AbstractAccountAuthenticator {

private Context context;

private final static String TAG = "GitHubAccountAuthenticator";

public AccountAuthenticator(final Context context) {
super(context);

Expand Down Expand Up @@ -75,7 +88,55 @@ public Bundle editProperties(AccountAuthenticatorResponse response,
public Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
return null;

final Bundle bundle = new Bundle();

if(!authTokenType.equals(ACCOUNT_TYPE)) return bundle;

AccountManager am = AccountManager.get(context);
String username = account.name;
String password = am.getPassword(account);

String authToken = null;
DefaultClient client = new DefaultClient();
client.setCredentials(username, password);

OAuthService oAuthService = new OAuthService(client);

// Get authorizations for app if they exist
try {
List<Authorization> auths = oAuthService.getAuthorizations();
for(Authorization auth : auths)
if(auth.getApp().getName().equals(ACCOUNT_NAME))
authToken = auth.getToken();

// Setup authorization for app if others didn't exist.
if(TextUtils.isEmpty(authToken)) {
Authorization auth = oAuthService.createAuthorization(
new Authorization().setNote(ACCOUNT_NAME).setUrl(APP_URL)
);
if(auth != null) authToken = auth.getToken();
}

// If couldn't get authToken
if(TextUtils.isEmpty(authToken)) {
final Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra(PARAM_AUTHTOKEN_TYPE, ACCOUNT_TYPE);
intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
bundle.putParcelable(KEY_INTENT, intent);
return bundle;
}

// Assemble and return bundle
bundle.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
bundle.putString(AccountManager.KEY_AUTHTOKEN, authToken);

// Clear password from account
am.clearPassword(account);
return bundle;
} catch ( Exception e ) { Log.e(TAG, e.getMessage()); }
return bundle;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.github.mobile.accounts;

import static android.util.Log.DEBUG;
import android.text.TextUtils;
import android.util.Log;

import com.github.mobile.DefaultClient;
Expand Down Expand Up @@ -54,7 +55,10 @@ protected HttpURLConnection configureRequest(final HttpURLConnection request) {
Log.d(TAG, "Authenticating using " + account);

// Credentials setting must come before super call
setCredentials(account.username, account.password);
if(!TextUtils.isEmpty(account.authToken)) // Use token if it exists
setOAuth2Token(account.authToken);
else
setCredentials(account.username, account.password);

return super.configureRequest(request);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@ public interface AccountConstants {
* Provider authority
*/
String PROVIDER_AUTHORITY = "com.github.sync";

/**
* Application URL
*/
String APP_URL = "https://github.com/github/android";
}
32 changes: 30 additions & 2 deletions app/src/main/java/com/github/mobile/accounts/AccountScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,27 @@

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;

import android.os.Bundle;
import android.util.Log;

import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.OutOfScopeException;

import java.io.IOException;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static com.github.mobile.accounts.AccountConstants.ACCOUNT_TYPE;

/**
* Custom scope that makes an authenticated GitHub account available by
* enforcing that the user is logged in before proceeding.
Expand All @@ -35,6 +47,8 @@ public class AccountScope extends ScopeBase {
private static final Key<GitHubAccount> GITHUB_ACCOUNT_KEY = Key
.get(GitHubAccount.class);

private static final String TAG = "GitHubAccountScope";

/**
* Create new module
*
Expand Down Expand Up @@ -66,8 +80,22 @@ AccountScope.<GitHubAccount> seededKeyProvider()).in(
*/
public void enterWith(final Account account,
final AccountManager accountManager) {
AccountManagerFuture future =
accountManager.getAuthToken(account, ACCOUNT_TYPE, null, true, null, null);

Bundle result = null;
String authToken = null;
try {
result = (Bundle) future.getResult();
authToken = result.getString(AccountManager.KEY_AUTHTOKEN);
}
catch (AuthenticatorException ae) { Log.e(TAG, ae.getMessage()); } // Authenticator failed to respond
catch (OperationCanceledException oce) { Log.e(TAG, oce.getMessage()); } // User canceled operation
catch (IOException ioe) { Log.e(TAG, ioe.getMessage()); } // Possible network issues

enterWith(new GitHubAccount(account.name,
accountManager.getPassword(account)));
accountManager.getPassword(account),
authToken));
}

/**
Expand Down Expand Up @@ -108,4 +136,4 @@ protected <T> Map<Key<?>, Object> getScopedObjectMap(final Key<T> key) {
}
return scopeMap;
}
}
}
11 changes: 10 additions & 1 deletion app/src/main/java/com/github/mobile/accounts/GitHubAccount.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.github.mobile.accounts;

import android.util.Log;

/**
* GitHub account model
*/
Expand All @@ -29,16 +31,23 @@ public class GitHubAccount {
* Account password
*/
public final String password;

/**
* Account password
*/
public final String authToken;

/**
* Create account with username and password
*
* @param username
* @param password
* @param authToken
*/
public GitHubAccount(String username, String password) {
public GitHubAccount(String username, String password, String authToken) {
this.username = username;
this.password = password;
this.authToken = authToken;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class UserComparatorTest extends AndroidTestCase {
* Test sorting of users that match login
*/
public void testLoginMatch() {
GitHubAccount account = new GitHubAccount("m", "n");
GitHubAccount account = new GitHubAccount("m", "n", "a");
UserComparator comparator = new UserComparator(account);

assertTrue(comparator.compare(new User().setLogin("m"),
Expand All @@ -52,7 +52,7 @@ public void testLoginMatch() {
* Test sorting of users that don't match login
*/
public void testNoLoginMatch() {
GitHubAccount account = new GitHubAccount("m", "n");
GitHubAccount account = new GitHubAccount("m", "n", "a");
UserComparator comparator = new UserComparator(account);

assertTrue(comparator.compare(new User().setLogin("a"),
Expand Down

0 comments on commit 13c6a7e

Please sign in to comment.