2FA support with pixelfed

This commit is contained in:
Thomas 2021-01-24 19:16:02 +01:00
parent 3f8142ee5a
commit 043beeecaf
8 changed files with 76 additions and 71 deletions

View File

@ -2565,10 +2565,7 @@ public abstract class BaseMainActivity extends BaseActivity
fragment.setArguments(bundle); fragment.setArguments(bundle);
return fragment; return fragment;
} else { } else {
DisplayStoriesFragment fragment = new DisplayStoriesFragment(); return new DisplayStoriesFragment();
bundle.putSerializable("type", RetrieveStoriesAsyncTask.type.ME);
fragment.setArguments(bundle);
return fragment;
} }
} }
} }

View File

@ -25,7 +25,6 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -164,33 +163,39 @@ public class WebviewConnectActivity extends BaseActivity {
@Override @Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
String x_xsrf_token = null;
String x_csrf_token = null;
if (request.getUrl().toString().contains("accounts/verify_credentials")) { if (request.getUrl().toString().contains("accounts/verify_credentials")) {
Log.v(Helper.TAG, "-> " + request.getUrl());
String cookies = CookieManager.getInstance().getCookie(request.getUrl().toString());
Map<String, String> requestHeaders = request.getRequestHeaders(); Map<String, String> requestHeaders = request.getRequestHeaders();
Iterator<Map.Entry<String, String>> it = requestHeaders.entrySet().iterator(); Iterator<Map.Entry<String, String>> it = requestHeaders.entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry<String, String> pair = it.next(); Map.Entry<String, String> pair = it.next();
Log.v(Helper.TAG, "pair.getKey() -> " + pair.getKey());
if (pair.getKey().compareTo("X-XSRF-TOKEN") == 0) { if (pair.getKey().compareTo("X-XSRF-TOKEN") == 0) {
new Handler(Looper.getMainLooper()).post(() -> { x_xsrf_token = pair.getValue();
pixelfedToken = pair.getValue(); }
Log.v(Helper.TAG, "pixelfedToken -> " + pixelfedToken); if (pair.getKey().compareTo("X-CSRF-TOKEN") == 0) {
view.stopLoading(); x_csrf_token = pair.getValue();
SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences1.edit();
String token = "X-XSRF-TOKEN: " + pixelfedToken;
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
editor.commit();
view.setVisibility(View.GONE);
//Update the account with the token;
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, clientId, clientSecret, null, instance, social);
finish();
});
} }
it.remove(); it.remove();
} }
if (x_xsrf_token != null && x_csrf_token != null) {
String finalX_xsrf_token = x_xsrf_token;
String finalX_csrf_token = x_csrf_token;
new Handler(Looper.getMainLooper()).post(() -> {
view.stopLoading();
SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences1.edit();
String token = "X-XSRF-TOKEN= " + finalX_xsrf_token + ";X-CSRF-TOKEN= " + finalX_csrf_token + "|" + cookies;
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
editor.commit();
view.setVisibility(View.GONE);
//Update the account with the token;
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, clientId, clientSecret, null, instance, social);
});
}
} }
return super.shouldInterceptRequest(view, request); return super.shouldInterceptRequest(view, request);
} }
@ -199,7 +204,6 @@ public class WebviewConnectActivity extends BaseActivity {
@Override @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { public boolean shouldOverrideUrlLoading(WebView view, String url) {
super.shouldOverrideUrlLoading(view, url); super.shouldOverrideUrlLoading(view, url);
Log.v(Helper.TAG, "pixelfedToken: " + pixelfedToken);
if (url.contains(Helper.REDIRECT_CONTENT_WEB)) { if (url.contains(Helper.REDIRECT_CONTENT_WEB)) {
String[] val = url.split("code="); String[] val = url.split("code=");
if (val.length < 2) { if (val.length < 2) {

View File

@ -36,34 +36,26 @@ public class RetrieveStoriesAsyncTask {
private final String max_id; private final String max_id;
private final OnRetrieveStoriesInterface listener; private final OnRetrieveStoriesInterface listener;
private final WeakReference<Context> contextReference; private final WeakReference<Context> contextReference;
private final type typeOfStory;
private APIResponse apiResponse; private APIResponse apiResponse;
private final String userId;
public RetrieveStoriesAsyncTask(Context context, String max_id, type typeOfStory, OnRetrieveStoriesInterface onRetrieveStoriesInterface) { public RetrieveStoriesAsyncTask(Context context, String max_id, String userId, OnRetrieveStoriesInterface onRetrieveStoriesInterface) {
this.contextReference = new WeakReference<>(context); this.contextReference = new WeakReference<>(context);
this.max_id = max_id; this.max_id = max_id;
this.listener = onRetrieveStoriesInterface; this.listener = onRetrieveStoriesInterface;
this.typeOfStory = typeOfStory; this.userId = userId;
doInBackground(); doInBackground();
} }
protected void doInBackground() { protected void doInBackground() {
new Thread(() -> { new Thread(() -> {
PixelfedAPI pixelfedAPI = new PixelfedAPI(this.contextReference.get()); PixelfedAPI pixelfedAPI = new PixelfedAPI(this.contextReference.get());
if (typeOfStory == type.FRIENDS) { apiResponse = pixelfedAPI.getFriendStories(userId, max_id);
apiResponse = pixelfedAPI.getFriendStories(max_id);
} else if (typeOfStory == type.ME) {
apiResponse = pixelfedAPI.getMyStories();
}
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> listener.onRetrieveStories(apiResponse); Runnable myRunnable = () -> listener.onRetrieveStories(apiResponse);
mainHandler.post(myRunnable); mainHandler.post(myRunnable);
}).start(); }).start();
} }
public enum type {
ME,
FRIENDS
}
} }

View File

@ -1461,9 +1461,12 @@ public class API {
} }
account.setUrl(resobj.getString("url")); account.setUrl(resobj.getString("url"));
account.setAvatar(resobj.getString("avatar")); account.setAvatar(resobj.getString("avatar"));
account.setAvatar_static(resobj.getString("avatar_static")); if (resobj.has("avatar_static"))
account.setHeader(resobj.getString("header")); account.setAvatar_static(resobj.getString("avatar_static"));
account.setHeader_static(resobj.getString("header_static")); if (resobj.has("header"))
account.setHeader(resobj.getString("header"));
if (resobj.has("header_static"))
account.setHeader_static(resobj.getString("header_static"));
try { try {
if (resobj.has("pleroma")) { if (resobj.has("pleroma")) {
account.setSocial("PLEROMA"); account.setSocial("PLEROMA");
@ -6235,7 +6238,12 @@ public class API {
} }
private String getAbsoluteUrl(String action) { private String getAbsoluteUrl(String action) {
return Helper.instanceWithProtocol(this.context, this.instance) + "/api/v1" + action; if (prefKeyOauthTokenT.startsWith("X-XSRF-TOKEN")) {
return Helper.instanceWithProtocol(this.context, this.instance) + "/api/pixelfed/v1" + action;
} else {
return Helper.instanceWithProtocol(this.context, this.instance) + "/api/v1" + action;
}
} }
private String getAbsoluteUr2l(String action) { private String getAbsoluteUr2l(String action) {

View File

@ -129,12 +129,18 @@ public class HttpsConnection {
private void setToken(String token) { private void setToken(String token) {
if (token != null) { if (token != null) {
if (token.startsWith("Basic ")) if (token.startsWith("Basic "))
httpURLConnection.setRequestProperty("Authorization", token); httpURLConnection.setRequestProperty("Authorization", token);
else if (token.startsWith("X-XSRF-TOKEN")) else if (token.startsWith("X-XSRF-TOKEN")) {
httpURLConnection.setRequestProperty("Authorization", token); String cookie = token.split("\\|")[1];
else httpURLConnection.setRequestProperty("cookie", cookie);
String[] tokens = token.split("\\|")[0].split(";");
httpURLConnection.setRequestProperty("x-xsrf-token", tokens[0].replace("X-XSRF-TOKEN= ", ""));
httpURLConnection.setRequestProperty("x-csrf-token", tokens[1].replace("X-CSRF-TOKEN= ", ""));
} else
httpURLConnection.setRequestProperty("Authorization", "Bearer " + token); httpURLConnection.setRequestProperty("Authorization", "Bearer " + token);
} }
} }

View File

@ -167,7 +167,7 @@ public class PixelfedAPI {
* *
* @return APIResponse * @return APIResponse
*/ */
public APIResponse getMyStories() { /* public APIResponse getMyStories() {
pixelFedStories = new ArrayList<>(); pixelFedStories = new ArrayList<>();
PixelFedStory pixelFedStory; PixelFedStory pixelFedStory;
try { try {
@ -187,21 +187,21 @@ public class PixelfedAPI {
apiResponse = new APIResponse(); apiResponse = new APIResponse();
apiResponse.setPixelFedStories(pixelFedStories); apiResponse.setPixelFedStories(pixelFedStories);
return apiResponse; return apiResponse;
} }*/
/** /**
* Retrieves Pixelfed Own Stories *synchronously* * Retrieves Pixelfed Own Stories *synchronously*
* *
* @return APIResponse * @return APIResponse
*/ */
public APIResponse getFriendStories(String max_id) { public APIResponse getFriendStories(String userId, String max_id) {
pixelFedStories = new ArrayList<>(); pixelFedStories = new ArrayList<>();
HashMap<String, String> params = new HashMap<>(); HashMap<String, String> params = new HashMap<>();
if (max_id != null) if (max_id != null)
params.put("max_id", max_id); params.put("max_id", max_id);
try { try {
HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); HttpsConnection httpsConnection = new HttpsConnection(context, this.instance);
String response = httpsConnection.get(getAbsoluteUrl("/recent"), 10, params, prefKeyOauthTokenT); String response = httpsConnection.get(getAbsoluteUrl("/fetch/" + userId), 10, params, prefKeyOauthTokenT);
apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setSince_id(httpsConnection.getSince_id());
apiResponse.setMax_id(httpsConnection.getMax_id()); apiResponse.setMax_id(httpsConnection.getMax_id());
pixelFedStories = parseStories(new JSONArray(response)); pixelFedStories = parseStories(new JSONArray(response));
@ -342,6 +342,6 @@ public class PixelfedAPI {
private String getAbsoluteUrl(String action) { private String getAbsoluteUrl(String action) {
return Helper.instanceWithProtocol(this.context, this.instance) + "/api/stories/v1" + action; return Helper.instanceWithProtocol(this.context, this.instance) + "/api/stories/v0" + action;
} }
} }

View File

@ -65,8 +65,8 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
private SwipeRefreshLayout swipeRefreshLayout; private SwipeRefreshLayout swipeRefreshLayout;
private boolean swiped; private boolean swiped;
private RecyclerView lv_stories; private RecyclerView lv_stories;
private RetrieveStoriesAsyncTask.type type;
private View rootView; private View rootView;
private String userId;
public DisplayStoriesFragment() { public DisplayStoriesFragment() {
} }
@ -77,10 +77,9 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
rootView = inflater.inflate(R.layout.fragment_stories, container, false); rootView = inflater.inflate(R.layout.fragment_stories, container, false);
Bundle bundle = this.getArguments();
if (bundle != null) { SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
type = (RetrieveStoriesAsyncTask.type) bundle.get("type"); userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
}
max_id = null; max_id = null;
context = getContext(); context = getContext();
@ -109,7 +108,7 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) { if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
if (!flag_loading) { if (!flag_loading) {
flag_loading = true; flag_loading = true;
new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this); new RetrieveStoriesAsyncTask(context, max_id, userId, DisplayStoriesFragment.this);
nextElementLoader.setVisibility(View.VISIBLE); nextElementLoader.setVisibility(View.VISIBLE);
} }
} else { } else {
@ -124,9 +123,8 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
flag_loading = true; flag_loading = true;
swiped = true; swiped = true;
if (context != null) if (context != null)
new RetrieveStoriesAsyncTask(context, null, type, DisplayStoriesFragment.this); new RetrieveStoriesAsyncTask(context, null, userId, DisplayStoriesFragment.this);
}); });
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme) { switch (theme) {
case Helper.THEME_LIGHT: case Helper.THEME_LIGHT:
@ -149,11 +147,11 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
break; break;
} }
if (context != null) if (context != null)
new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this); new RetrieveStoriesAsyncTask(context, max_id, userId, DisplayStoriesFragment.this);
else else
new Handler(Looper.getMainLooper()).postDelayed(() -> { new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (context != null) if (context != null)
new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this); new RetrieveStoriesAsyncTask(context, max_id, userId, DisplayStoriesFragment.this);
}, 500); }, 500);
return rootView; return rootView;
} }
@ -259,7 +257,7 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
* @param sinceId String * @param sinceId String
*/ */
private void retrieveMissingNotifications(String sinceId) { private void retrieveMissingNotifications(String sinceId) {
new RetrieveStoriesAsyncTask(context, null, type, DisplayStoriesFragment.this); new RetrieveStoriesAsyncTask(context, null, userId, DisplayStoriesFragment.this);
} }
@Override @Override

View File

@ -66,10 +66,10 @@ public class AccountDAO {
values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count()); values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count());
values.put(Sqlite.COL_NOTE, account.getNote()); values.put(Sqlite.COL_NOTE, account.getNote());
values.put(Sqlite.COL_URL, account.getUrl()); values.put(Sqlite.COL_URL, account.getUrl());
values.put(Sqlite.COL_AVATAR, account.getAvatar()); values.put(Sqlite.COL_AVATAR, account.getAvatar() != null ? account.getAvatar() : "null");
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static()); values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static() != null ? account.getAvatar_static() : "null");
values.put(Sqlite.COL_HEADER, account.getHeader()); values.put(Sqlite.COL_HEADER, account.getHeader() != null ? account.getHeader() : "null");
values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static()); values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static() != null ? account.getHeader_static() : "---");
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at())); values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at()));
values.put(Sqlite.COL_INSTANCE, account.getInstance()); values.put(Sqlite.COL_INSTANCE, account.getInstance());
values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis())); values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis()));
@ -117,10 +117,10 @@ public class AccountDAO {
values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count()); values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count());
values.put(Sqlite.COL_NOTE, account.getNote()); values.put(Sqlite.COL_NOTE, account.getNote());
values.put(Sqlite.COL_URL, account.getUrl()); values.put(Sqlite.COL_URL, account.getUrl());
values.put(Sqlite.COL_AVATAR, account.getAvatar()); values.put(Sqlite.COL_AVATAR, account.getAvatar() != null ? account.getAvatar() : "null");
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static()); values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static() != null ? account.getAvatar_static() : "null");
values.put(Sqlite.COL_HEADER, account.getHeader()); values.put(Sqlite.COL_HEADER, account.getHeader() != null ? account.getHeader() : "null");
values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static()); values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static() != null ? account.getHeader_static() : "null");
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at())); values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at()));
values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis())); values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis()));
if (account.getSocial() != null) { if (account.getSocial() != null) {
@ -168,10 +168,10 @@ public class AccountDAO {
values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count()); values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count());
values.put(Sqlite.COL_NOTE, account.getNote()); values.put(Sqlite.COL_NOTE, account.getNote());
values.put(Sqlite.COL_URL, account.getUrl()); values.put(Sqlite.COL_URL, account.getUrl());
values.put(Sqlite.COL_AVATAR, account.getAvatar()); values.put(Sqlite.COL_AVATAR, account.getAvatar() != null ? account.getAvatar() : "null");
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static()); values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static() != null ? account.getAvatar_static() : "null");
values.put(Sqlite.COL_HEADER, account.getHeader()); values.put(Sqlite.COL_HEADER, account.getHeader() != null ? account.getHeader() : "null");
values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static()); values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static() != null ? account.getHeader_static() : "null");
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at())); values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at()));
values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis())); values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis()));
if (account.getSocial() != null) { if (account.getSocial() != null) {