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);
return fragment;
} else {
DisplayStoriesFragment fragment = new DisplayStoriesFragment();
bundle.putSerializable("type", RetrieveStoriesAsyncTask.type.ME);
fragment.setArguments(bundle);
return fragment;
return new DisplayStoriesFragment();
}
}
}

View File

@ -25,7 +25,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -164,33 +163,39 @@ public class WebviewConnectActivity extends BaseActivity {
@Override
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")) {
Log.v(Helper.TAG, "-> " + request.getUrl());
String cookies = CookieManager.getInstance().getCookie(request.getUrl().toString());
Map<String, String> requestHeaders = request.getRequestHeaders();
Iterator<Map.Entry<String, String>> it = requestHeaders.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
Log.v(Helper.TAG, "pair.getKey() -> " + pair.getKey());
if (pair.getKey().compareTo("X-XSRF-TOKEN") == 0) {
new Handler(Looper.getMainLooper()).post(() -> {
pixelfedToken = pair.getValue();
Log.v(Helper.TAG, "pixelfedToken -> " + pixelfedToken);
view.stopLoading();
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();
});
x_xsrf_token = pair.getValue();
}
if (pair.getKey().compareTo("X-CSRF-TOKEN") == 0) {
x_csrf_token = pair.getValue();
}
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);
}
@ -199,7 +204,6 @@ public class WebviewConnectActivity extends BaseActivity {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
super.shouldOverrideUrlLoading(view, url);
Log.v(Helper.TAG, "pixelfedToken: " + pixelfedToken);
if (url.contains(Helper.REDIRECT_CONTENT_WEB)) {
String[] val = url.split("code=");
if (val.length < 2) {

View File

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

View File

@ -1461,9 +1461,12 @@ public class API {
}
account.setUrl(resobj.getString("url"));
account.setAvatar(resobj.getString("avatar"));
account.setAvatar_static(resobj.getString("avatar_static"));
account.setHeader(resobj.getString("header"));
account.setHeader_static(resobj.getString("header_static"));
if (resobj.has("avatar_static"))
account.setAvatar_static(resobj.getString("avatar_static"));
if (resobj.has("header"))
account.setHeader(resobj.getString("header"));
if (resobj.has("header_static"))
account.setHeader_static(resobj.getString("header_static"));
try {
if (resobj.has("pleroma")) {
account.setSocial("PLEROMA");
@ -6235,7 +6238,12 @@ public class API {
}
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) {

View File

@ -129,12 +129,18 @@ public class HttpsConnection {
private void setToken(String token) {
if (token != null) {
if (token.startsWith("Basic "))
httpURLConnection.setRequestProperty("Authorization", token);
else if (token.startsWith("X-XSRF-TOKEN"))
httpURLConnection.setRequestProperty("Authorization", token);
else
else if (token.startsWith("X-XSRF-TOKEN")) {
String cookie = token.split("\\|")[1];
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);
}
}

View File

@ -167,7 +167,7 @@ public class PixelfedAPI {
*
* @return APIResponse
*/
public APIResponse getMyStories() {
/* public APIResponse getMyStories() {
pixelFedStories = new ArrayList<>();
PixelFedStory pixelFedStory;
try {
@ -187,21 +187,21 @@ public class PixelfedAPI {
apiResponse = new APIResponse();
apiResponse.setPixelFedStories(pixelFedStories);
return apiResponse;
}
}*/
/**
* Retrieves Pixelfed Own Stories *synchronously*
*
* @return APIResponse
*/
public APIResponse getFriendStories(String max_id) {
public APIResponse getFriendStories(String userId, String max_id) {
pixelFedStories = new ArrayList<>();
HashMap<String, String> params = new HashMap<>();
if (max_id != null)
params.put("max_id", max_id);
try {
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.setMax_id(httpsConnection.getMax_id());
pixelFedStories = parseStories(new JSONArray(response));
@ -342,6 +342,6 @@ public class PixelfedAPI {
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 boolean swiped;
private RecyclerView lv_stories;
private RetrieveStoriesAsyncTask.type type;
private View rootView;
private String userId;
public DisplayStoriesFragment() {
}
@ -77,10 +77,9 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
rootView = inflater.inflate(R.layout.fragment_stories, container, false);
Bundle bundle = this.getArguments();
if (bundle != null) {
type = (RetrieveStoriesAsyncTask.type) bundle.get("type");
}
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
max_id = null;
context = getContext();
@ -109,7 +108,7 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
if (!flag_loading) {
flag_loading = true;
new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this);
new RetrieveStoriesAsyncTask(context, max_id, userId, DisplayStoriesFragment.this);
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
@ -124,9 +123,8 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
flag_loading = true;
swiped = true;
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);
switch (theme) {
case Helper.THEME_LIGHT:
@ -149,11 +147,11 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
break;
}
if (context != null)
new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this);
new RetrieveStoriesAsyncTask(context, max_id, userId, DisplayStoriesFragment.this);
else
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (context != null)
new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this);
new RetrieveStoriesAsyncTask(context, max_id, userId, DisplayStoriesFragment.this);
}, 500);
return rootView;
}
@ -259,7 +257,7 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie
* @param sinceId String
*/
private void retrieveMissingNotifications(String sinceId) {
new RetrieveStoriesAsyncTask(context, null, type, DisplayStoriesFragment.this);
new RetrieveStoriesAsyncTask(context, null, userId, DisplayStoriesFragment.this);
}
@Override

View File

@ -66,10 +66,10 @@ public class AccountDAO {
values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count());
values.put(Sqlite.COL_NOTE, account.getNote());
values.put(Sqlite.COL_URL, account.getUrl());
values.put(Sqlite.COL_AVATAR, account.getAvatar());
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static());
values.put(Sqlite.COL_HEADER, account.getHeader());
values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static());
values.put(Sqlite.COL_AVATAR, account.getAvatar() != null ? account.getAvatar() : "null");
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static() != null ? account.getAvatar_static() : "null");
values.put(Sqlite.COL_HEADER, account.getHeader() != null ? account.getHeader() : "null");
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_INSTANCE, account.getInstance());
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_NOTE, account.getNote());
values.put(Sqlite.COL_URL, account.getUrl());
values.put(Sqlite.COL_AVATAR, account.getAvatar());
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static());
values.put(Sqlite.COL_HEADER, account.getHeader());
values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static());
values.put(Sqlite.COL_AVATAR, account.getAvatar() != null ? account.getAvatar() : "null");
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static() != null ? account.getAvatar_static() : "null");
values.put(Sqlite.COL_HEADER, account.getHeader() != null ? account.getHeader() : "null");
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_EMOJIS, Helper.emojisToStringStorage(account.getEmojis()));
if (account.getSocial() != null) {
@ -168,10 +168,10 @@ public class AccountDAO {
values.put(Sqlite.COL_STATUSES_COUNT, account.getStatuses_count());
values.put(Sqlite.COL_NOTE, account.getNote());
values.put(Sqlite.COL_URL, account.getUrl());
values.put(Sqlite.COL_AVATAR, account.getAvatar());
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static());
values.put(Sqlite.COL_HEADER, account.getHeader());
values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static());
values.put(Sqlite.COL_AVATAR, account.getAvatar() != null ? account.getAvatar() : "null");
values.put(Sqlite.COL_AVATAR_STATIC, account.getAvatar_static() != null ? account.getAvatar_static() : "null");
values.put(Sqlite.COL_HEADER, account.getHeader() != null ? account.getHeader() : "null");
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_EMOJIS, Helper.emojisToStringStorage(account.getEmojis()));
if (account.getSocial() != null) {