diff --git a/app/.classpath b/app/.classpath
index a0c1af6..f54935b 100644
--- a/app/.classpath
+++ b/app/.classpath
@@ -7,5 +7,7 @@
+
+
diff --git a/app/libs/signpost-commonshttp4-1.2.1.1.jar b/app/libs/signpost-commonshttp4-1.2.1.1.jar
new file mode 100644
index 0000000..50e9838
Binary files /dev/null and b/app/libs/signpost-commonshttp4-1.2.1.1.jar differ
diff --git a/app/libs/signpost-core-1.2.1.1.jar b/app/libs/signpost-core-1.2.1.1.jar
new file mode 100644
index 0000000..59e7537
Binary files /dev/null and b/app/libs/signpost-core-1.2.1.1.jar differ
diff --git a/app/res/values/settings.xml b/app/res/values/settings.xml
index 0a40460..99b2438 100644
--- a/app/res/values/settings.xml
+++ b/app/res/values/settings.xml
@@ -12,6 +12,12 @@
setting_loggedin
Log out
Log in
+ setting_loggedin
+
+ setting_oauth_consumer_key
+ setting_oauth_consumer_secret
+ setting_oauth_token
+ setting_oauth_token_secret
Edit account
Change profile picture
@@ -22,4 +28,5 @@
setting_autoupload_tag
autoupload
+
diff --git a/app/src/me/openphoto/android/app/GalleryActivity.java b/app/src/me/openphoto/android/app/GalleryActivity.java
index 9cacfb3..9c1a1b9 100644
--- a/app/src/me/openphoto/android/app/GalleryActivity.java
+++ b/app/src/me/openphoto/android/app/GalleryActivity.java
@@ -9,7 +9,6 @@ import java.util.List;
import me.openphoto.android.app.model.Photo;
import me.openphoto.android.app.net.IOpenPhotoApi;
-import me.openphoto.android.app.net.OpenPhotoApi;
import me.openphoto.android.app.net.Paging;
import me.openphoto.android.app.net.PhotosResponse;
import me.openphoto.android.app.net.ReturnSize;
@@ -82,8 +81,7 @@ public class GalleryActivity extends Activity implements OnItemClickListener {
public PhotosEndlessAdapter(String tagFilter) {
super();
- mOpenPhotoApi = OpenPhotoApi
- .createInstance(Preferences.getServer(GalleryActivity.this));
+ mOpenPhotoApi = Preferences.getApi(GalleryActivity.this);
mTagFilter = new ArrayList(1);
if (tagFilter != null) {
mTagFilter.add(tagFilter);
diff --git a/app/src/me/openphoto/android/app/MainActivity.java b/app/src/me/openphoto/android/app/MainActivity.java
index ff062de..9d80242 100644
--- a/app/src/me/openphoto/android/app/MainActivity.java
+++ b/app/src/me/openphoto/android/app/MainActivity.java
@@ -8,7 +8,6 @@ import java.net.URL;
import me.openphoto.android.app.model.Photo;
import me.openphoto.android.app.net.IOpenPhotoApi;
-import me.openphoto.android.app.net.OpenPhotoApi;
import me.openphoto.android.app.net.Paging;
import me.openphoto.android.app.net.ReturnSize;
import me.openphoto.android.app.ui.widget.ActionBar;
@@ -52,7 +51,7 @@ public class MainActivity extends Activity implements OnClickListener {
mActionBar = (ActionBar) findViewById(R.id.actionbar);
new LoadImageTask().execute();
- // Get refereneces to navigation buttons
+ // Get references to navigation buttons
searchBtn = (ImageButton) findViewById(R.id.main_search_btn);
cameraBtn = (ImageButton) findViewById(R.id.main_camera_btn);
galleryBtn = (ImageButton) findViewById(R.id.main_gallery_btn);
@@ -73,8 +72,7 @@ public class MainActivity extends Activity implements OnClickListener {
@Override
protected Bitmap doInBackground(Void... params) {
- IOpenPhotoApi api = OpenPhotoApi
- .createInstance(Preferences.getServer(MainActivity.this));
+ IOpenPhotoApi api = Preferences.getApi(MainActivity.this);
try {
Photo photo = api.getPhotos(new ReturnSize(600, 600), null, new Paging(1, 1))
.getPhotos().get(0);
diff --git a/app/src/me/openphoto/android/app/OAuthActivity.java b/app/src/me/openphoto/android/app/OAuthActivity.java
index 8d63508..62fa769 100644
--- a/app/src/me/openphoto/android/app/OAuthActivity.java
+++ b/app/src/me/openphoto/android/app/OAuthActivity.java
@@ -1,28 +1,21 @@
package me.openphoto.android.app;
-import java.net.URL;
-
-import me.openphoto.android.app.model.Photo;
import me.openphoto.android.app.net.IOpenPhotoApi;
-import me.openphoto.android.app.net.OpenPhotoApi;
-import me.openphoto.android.app.net.Paging;
-import me.openphoto.android.app.net.ReturnSize;
import me.openphoto.android.app.ui.widget.ActionBar;
+import oauth.signpost.OAuthConsumer;
+import oauth.signpost.OAuthProvider;
+import oauth.signpost.basic.DefaultOAuthConsumer;
import android.app.Activity;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
-import android.view.View;
-import android.webkit.CookieManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.widget.ImageView;
import android.widget.Toast;
/**
@@ -51,49 +44,59 @@ public class OAuthActivity extends Activity {
setContentView(R.layout.oauth);
mActionBar = (ActionBar) findViewById(R.id.actionbar);
+ // CookieSyncManager.createInstance(this);
+ // CookieSyncManager.getInstance().startSync();
+ // CookieManager cookieManager = CookieManager.getInstance();
+ // cookieManager.setAcceptCookie(true);
+
mWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = mWebView.getSettings();
- webSettings.setSavePassword(false);
webSettings.setJavaScriptEnabled(true);
+ // webSettings.setSupportMultipleWindows(true);
+ // webSettings.setDatabaseEnabled(true);
+ // String databasePath = getApplicationContext().getDir("database",
+ // Context.MODE_PRIVATE)
+ // .getPath();
+ // webSettings.setDatabasePath(databasePath);
mWebView.setWebChromeClient(mWebChromeClient);
mWebView.setWebViewClient(mWebViewClient);
- CookieManager cookieManager = CookieManager.getInstance();
- cookieManager.setAcceptCookie(false);
-
- mOpenPhoto = OpenPhotoApi.createInstance(Preferences.getServer(this));
+ mOpenPhoto = Preferences.getApi(this);
String url = mOpenPhoto.getOAuthUrl(CALLBACK);
mWebView.loadUrl(url);
}
private final WebChromeClient mWebChromeClient = new WebChromeClient() {
- private boolean mIsLoading = false;
@Override
- public void onProgressChanged(WebView view, int newProgress) {
- super.onProgressChanged(view, newProgress);
- if (newProgress < 100) {
- if (!mIsLoading) {
- mIsLoading = true;
- mActionBar.startLoading();
- }
- } else if (mIsLoading) {
- mActionBar.stopLoading();
- mIsLoading = false;
- }
+ public void onConsoleMessage(String message, int lineNumber, String sourceID) {
+ Log.e(TAG, "Error: " + message);
+ super.onConsoleMessage(message, lineNumber, sourceID);
}
};
private final WebViewClient mWebViewClient = new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ mActionBar.stopLoading();
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ super.onPageStarted(view, url, favicon);
+ mActionBar.startLoading();
+ }
+
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
boolean result = true;
if ((url != null) && (url.startsWith(CALLBACK))) {
Uri uri = Uri.parse(url);
- if (uri.getQueryParameter("token") != null) {
- new PostTask().execute();
+ if (uri.getQueryParameter("oauth_token") != null) {
+ new PostTask(uri).execute();
} else {
Toast.makeText(OAuthActivity.this, "Error: " + uri.getQueryParameter("error"),
Toast.LENGTH_LONG).show();
@@ -104,10 +107,15 @@ public class OAuthActivity extends Activity {
}
return result;
}
-
};
- private class PostTask extends AsyncTask {
+ private class PostTask extends AsyncTask {
+ private final Uri mUri;
+ private OAuthConsumer mUsedConsumer;
+
+ public PostTask(Uri uri) {
+ mUri = uri;
+ }
@Override
protected void onPreExecute() {
@@ -116,34 +124,33 @@ public class OAuthActivity extends Activity {
}
@Override
- protected Bitmap doInBackground(Void... params) {
- IOpenPhotoApi api = OpenPhotoApi
- .createInstance(Preferences.getServer(OAuthActivity.this));
+ protected Boolean doInBackground(Void... params) {
try {
- Photo photo = api.getPhotos(new ReturnSize(600, 600), null, new Paging(1, 1))
- .getPhotos().get(0);
- // TODO do not use base, make getPhotos actually use a
- // returnSize parameter that should be used then.
- return BitmapFactory.decodeStream(new URL(photo
- .getUrl("600x600")).openStream());
+ String oAuthConsumerKey = mUri.getQueryParameter("oauth_consumer_key");
+ String oAuthConsumerSecret = mUri.getQueryParameter("oauth_consumer_secret");
+ String oAuthToken = mUri.getQueryParameter("oauth_token");
+ String oAuthTokenSecret = mUri.getQueryParameter("oauth_token_secret");
+ String oAuthVerifier = mUri.getQueryParameter("oauth_verifier");
+
+ mUsedConsumer = new DefaultOAuthConsumer(oAuthConsumerKey,
+ oAuthConsumerSecret);
+ mUsedConsumer.setTokenWithSecret(oAuthToken, oAuthTokenSecret);
+
+ OAuthProvider provider = Preferences.getOAuthProvider(OAuthActivity.this);
+ provider.retrieveAccessToken(mUsedConsumer, oAuthVerifier);
+ return true;
} catch (Exception e) {
- Log.w(TAG, "Error while getting image", e);
- return null;
+ return false;
}
}
@Override
- protected void onPostExecute(Bitmap result) {
+ protected void onPostExecute(Boolean result) {
mActionBar.stopLoading();
- if (result != null) {
- ImageView image = (ImageView) findViewById(R.id.image);
- image.setImageBitmap(result);
- image.setVisibility(View.VISIBLE);
- } else {
- Toast.makeText(OAuthActivity.this, "Could not download image",
- Toast.LENGTH_LONG).show();
+ if (result.booleanValue()) {
+ Preferences.setLoginInformation(OAuthActivity.this, mUsedConsumer);
+ finish();
}
}
-
}
}
diff --git a/app/src/me/openphoto/android/app/Preferences.java b/app/src/me/openphoto/android/app/Preferences.java
index fbf24cd..184867e 100644
--- a/app/src/me/openphoto/android/app/Preferences.java
+++ b/app/src/me/openphoto/android/app/Preferences.java
@@ -1,7 +1,14 @@
package me.openphoto.android.app;
+import me.openphoto.android.app.net.IOpenPhotoApi;
+import me.openphoto.android.app.net.OpenPhotoApi;
+import oauth.signpost.OAuthConsumer;
+import oauth.signpost.OAuthProvider;
+import oauth.signpost.basic.DefaultOAuthProvider;
+import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import android.content.Context;
+import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class Preferences {
@@ -31,10 +38,65 @@ public class Preferences {
.getBoolean(context.getString(R.string.setting_account_loggedin_key), false);
}
- public static void setLoggedIn(Context context, boolean loggedIn) {
+ public static void logout(Context context) {
PreferenceManager.getDefaultSharedPreferences(context)
.edit()
- .putBoolean(context.getString(R.string.setting_account_loggedin_key), loggedIn)
+ .putBoolean(context.getString(R.string.setting_account_loggedin_key), false)
+ .commit();
+ context.getSharedPreferences("oauth", Context.MODE_PRIVATE)
+ .edit()
+ .clear()
.commit();
}
+
+ public static void setLoginInformation(Context context, OAuthConsumer consumer) {
+ PreferenceManager.getDefaultSharedPreferences(context)
+ .edit()
+ .putBoolean(context.getString(R.string.setting_account_loggedin_key), true)
+ .commit();
+ context.getSharedPreferences("oauth", Context.MODE_PRIVATE)
+ .edit()
+ .putString(context.getString(R.string.setting_oauth_consumer_key),
+ consumer.getConsumerKey())
+ .putString(context.getString(R.string.setting_oauth_consumer_secret),
+ consumer.getConsumerSecret())
+ .putString(context.getString(R.string.setting_oauth_token),
+ consumer.getToken())
+ .putString(context.getString(R.string.setting_oauth_token_secret),
+ consumer.getTokenSecret())
+ .commit();
+ }
+
+ public static OAuthProvider getOAuthProvider(Context context) {
+ String serverUrl = getServer(context);
+ OAuthProvider provider = new DefaultOAuthProvider(
+ serverUrl + "/v1/oauth/token/request",
+ serverUrl + "/v1/oauth/token/access",
+ serverUrl + "/v1/oauth/authorize");
+ provider.setOAuth10a(true);
+ return provider;
+ }
+
+ public static IOpenPhotoApi getApi(Context context) {
+ IOpenPhotoApi api = OpenPhotoApi.createInstance(getServer(context));
+ if (isLoggedIn(context)) {
+ api.setOAuthConsumer(getOAuthConsumer(context));
+ }
+ return api;
+ }
+
+ private static OAuthConsumer getOAuthConsumer(Context context) {
+ if (!isLoggedIn(context)) {
+ throw new IllegalAccessError("User is not logged in, so can not call this method!");
+ }
+
+ SharedPreferences prefs = context.getSharedPreferences("oauth", Context.MODE_PRIVATE);
+ OAuthConsumer consumer = new CommonsHttpOAuthConsumer(
+ prefs.getString(context.getString(R.string.setting_oauth_consumer_key), null),
+ prefs.getString(context.getString(R.string.setting_oauth_consumer_secret), null));
+ consumer.setTokenWithSecret(
+ prefs.getString(context.getString(R.string.setting_oauth_token), null),
+ prefs.getString(context.getString(R.string.setting_oauth_token_secret), null));
+ return consumer;
+ }
}
diff --git a/app/src/me/openphoto/android/app/SearchActivity.java b/app/src/me/openphoto/android/app/SearchActivity.java
index d6f0eaa..c79d390 100644
--- a/app/src/me/openphoto/android/app/SearchActivity.java
+++ b/app/src/me/openphoto/android/app/SearchActivity.java
@@ -6,7 +6,6 @@ package me.openphoto.android.app;
import me.openphoto.android.app.model.Tag;
import me.openphoto.android.app.net.IOpenPhotoApi;
-import me.openphoto.android.app.net.OpenPhotoApi;
import me.openphoto.android.app.net.TagsResponse;
import me.openphoto.android.app.ui.adapter.EndlessAdapter;
import me.openphoto.android.app.ui.widget.ActionBar;
@@ -88,8 +87,7 @@ public class SearchActivity extends Activity implements OnItemClickListener {
public TagsAdapter() {
super();
- mOpenPhotoApi = OpenPhotoApi
- .createInstance(Preferences.getServer(SearchActivity.this));
+ mOpenPhotoApi = Preferences.getApi(SearchActivity.this);
}
@Override
diff --git a/app/src/me/openphoto/android/app/SettingsActivity.java b/app/src/me/openphoto/android/app/SettingsActivity.java
index bcbab62..3c18b26 100644
--- a/app/src/me/openphoto/android/app/SettingsActivity.java
+++ b/app/src/me/openphoto/android/app/SettingsActivity.java
@@ -36,15 +36,23 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
@Override
protected void onResume() {
super.onResume();
+ refreshLoginPreferenceTitle();
+ }
+
+ private void refreshLoginPreferenceTitle() {
mLoginPreference.setTitle(Preferences.isLoggedIn(this) ?
R.string.setting_account_loggedin_logout : R.string.setting_account_loggedin_login);
}
+ // TODO when server is changed it should delete the login information
+
@Override
public boolean onPreferenceClick(Preference preference) {
if (getString(R.string.setting_account_loggedin_key).equals(preference.getKey())) {
if (Preferences.isLoggedIn(this)) {
-
+ // TODO show logout confirmation dialog
+ Preferences.logout(this);
+ refreshLoginPreferenceTitle();
} else {
startActivity(new Intent(this, OAuthActivity.class));
}
diff --git a/app/src/me/openphoto/android/app/UploadActivity.java b/app/src/me/openphoto/android/app/UploadActivity.java
index aac1b26..ca0fba8 100644
--- a/app/src/me/openphoto/android/app/UploadActivity.java
+++ b/app/src/me/openphoto/android/app/UploadActivity.java
@@ -5,7 +5,6 @@ import java.io.File;
import java.io.IOException;
import java.util.Date;
-import me.openphoto.android.app.net.OpenPhotoApi;
import me.openphoto.android.app.net.UploadMetaData;
import me.openphoto.android.app.net.UploadResponse;
import me.openphoto.android.app.util.FileUtils;
@@ -188,8 +187,7 @@ public class UploadActivity extends Activity implements OnClickListener {
// TODO add private and effects aviary
try {
- return OpenPhotoApi.createInstance(Preferences.getServer(UploadActivity.this))
- .uploadPhoto(params[0], metaData);
+ return Preferences.getApi(UploadActivity.this).uploadPhoto(params[0], metaData);
} catch (Exception e) {
Log.e(TAG, "Error while uploading", e);
}
diff --git a/app/src/me/openphoto/android/app/ViewPhotoActivity.java b/app/src/me/openphoto/android/app/ViewPhotoActivity.java
index 5b6657a..775df24 100644
--- a/app/src/me/openphoto/android/app/ViewPhotoActivity.java
+++ b/app/src/me/openphoto/android/app/ViewPhotoActivity.java
@@ -5,7 +5,6 @@
package me.openphoto.android.app;
import me.openphoto.android.app.model.Photo;
-import me.openphoto.android.app.net.OpenPhotoApi;
import me.openphoto.android.app.net.PhotoResponse;
import me.openphoto.android.app.net.ReturnSize;
import me.openphoto.android.app.ui.lib.ImageStorage;
@@ -86,9 +85,8 @@ public class ViewPhotoActivity extends Activity implements OnClickListener {
@Override
protected Photo doInBackground(Void... params) {
try {
- PhotoResponse response = OpenPhotoApi.createInstance(
- Preferences.getServer(ViewPhotoActivity.this)).getPhoto(mPhoto.getId(),
- new ReturnSize(1024, 1024));
+ PhotoResponse response = Preferences.getApi(ViewPhotoActivity.this)
+ .getPhoto(mPhoto.getId(), new ReturnSize(1024, 1024));
return response.getPhoto();
} catch (Exception e) {
return null;
diff --git a/app/src/me/openphoto/android/app/net/ApiBase.java b/app/src/me/openphoto/android/app/net/ApiBase.java
index a990628..a0c1e73 100644
--- a/app/src/me/openphoto/android/app/net/ApiBase.java
+++ b/app/src/me/openphoto/android/app/net/ApiBase.java
@@ -7,6 +7,7 @@ import java.io.UnsupportedEncodingException;
import java.util.List;
import me.openphoto.android.app.net.ApiRequest.Parameter;
+import oauth.signpost.OAuthConsumer;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
@@ -33,6 +34,7 @@ import org.apache.http.protocol.HTTP;
*/
public class ApiBase {
private final String mBaseUrl;
+ private OAuthConsumer mOAuthConsumer;
/**
* Instantiates a new ApiBase object.
@@ -46,6 +48,16 @@ public class ApiBase {
mBaseUrl = baseUrl;
}
+ /**
+ * Sets the OAuthConsumer when the calls with the server need to be
+ * authenticated.
+ *
+ * @param oAuthConsumer
+ */
+ public void setOAuthConsumer(OAuthConsumer oAuthConsumer) {
+ mOAuthConsumer = oAuthConsumer;
+ }
+
/**
* Gets the base url of the used API.
*
@@ -70,7 +82,14 @@ public class ApiBase {
HttpUriRequest httpRequest = createHttpRequest(request);
httpRequest.getParams().setBooleanParameter("http.protocol.expect-continue", false);
-
+ if (mOAuthConsumer != null) {
+ try {
+ mOAuthConsumer.sign(httpRequest);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
return new ApiResponse(httpClient.execute(httpRequest));
}
diff --git a/app/src/me/openphoto/android/app/net/IOpenPhotoApi.java b/app/src/me/openphoto/android/app/net/IOpenPhotoApi.java
index 1dc4c56..41758b2 100644
--- a/app/src/me/openphoto/android/app/net/IOpenPhotoApi.java
+++ b/app/src/me/openphoto/android/app/net/IOpenPhotoApi.java
@@ -5,11 +5,21 @@ import java.io.File;
import java.io.IOException;
import java.util.Collection;
+import oauth.signpost.OAuthConsumer;
+
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
public interface IOpenPhotoApi {
+ /**
+ * Sets the OAuthConsumer when the calls with the server need to be
+ * authenticated.
+ *
+ * @param oAuthConsumer
+ */
+ void setOAuthConsumer(OAuthConsumer oAuthConsumer);
+
/**
* @return tags which are used on the server
* @throws ClientProtocolException
diff --git a/app/src/me/openphoto/android/app/net/OpenPhotoApi.java b/app/src/me/openphoto/android/app/net/OpenPhotoApi.java
index 6c56050..af39835 100644
--- a/app/src/me/openphoto/android/app/net/OpenPhotoApi.java
+++ b/app/src/me/openphoto/android/app/net/OpenPhotoApi.java
@@ -6,6 +6,8 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
+import oauth.signpost.OAuthConsumer;
+
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.json.JSONObject;
@@ -36,6 +38,21 @@ public class OpenPhotoApi extends ApiBase implements IOpenPhotoApi {
}
}
+ /*
+ * (non-Javadoc)
+ * @see
+ * me.openphoto.android.app.net.IOpenPhotoApi#setOAuthConsumer(oauth.signpost
+ * .OAuthConsumer)
+ */
+ @Override
+ public void setOAuthConsumer(OAuthConsumer oAuthConsumer) {
+ super.setOAuthConsumer(oAuthConsumer);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see me.openphoto.android.app.net.IOpenPhotoApi#getTags()
+ */
@Override
public TagsResponse getTags() throws ClientProtocolException, IOException,
IllegalStateException, JSONException {
@@ -68,7 +85,7 @@ public class OpenPhotoApi extends ApiBase implements IOpenPhotoApi {
*/
@Override
public String getOAuthUrl(String callback) {
- return getBaseUrl() + "/v1/oauth/authorize";
+ return getBaseUrl() + "/v1/oauth/authorize?mobile=1&oauth_callback=" + callback;
}
/*
diff --git a/app/src/me/openphoto/android/app/service/UploaderService.java b/app/src/me/openphoto/android/app/service/UploaderService.java
index cd866ed..16c1c6d 100644
--- a/app/src/me/openphoto/android/app/service/UploaderService.java
+++ b/app/src/me/openphoto/android/app/service/UploaderService.java
@@ -6,7 +6,6 @@ import java.util.Calendar;
import me.openphoto.android.app.Preferences;
import me.openphoto.android.app.net.IOpenPhotoApi;
-import me.openphoto.android.app.net.OpenPhotoApi;
import me.openphoto.android.app.net.UploadMetaData;
import me.openphoto.android.app.provider.UploadsProvider;
import me.openphoto.android.app.util.ImageUtils;
@@ -31,7 +30,7 @@ public class UploaderService extends IntentService {
@Override
public void onCreate() {
super.onCreate();
- mApi = OpenPhotoApi.createInstance(Preferences.getServer(this));
+ mApi = Preferences.getApi(this);
}
@Override