Implement logic
This commit is contained in:
parent
439decf6a9
commit
bbfa278d6b
|
@ -50,6 +50,7 @@ android {
|
||||||
buildConfigField "boolean", "surfing_mode", "false"
|
buildConfigField "boolean", "surfing_mode", "false"
|
||||||
buildConfigField "boolean", "sepia_search", "false"
|
buildConfigField "boolean", "sepia_search", "false"
|
||||||
buildConfigField "boolean", "instance_switcher", "true"
|
buildConfigField "boolean", "instance_switcher", "true"
|
||||||
|
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||||
}
|
}
|
||||||
google_peertube_apps_educ {
|
google_peertube_apps_educ {
|
||||||
applicationId "app.fedilab.fedilabtube"
|
applicationId "app.fedilab.fedilabtube"
|
||||||
|
@ -61,6 +62,7 @@ android {
|
||||||
buildConfigField "boolean", "surfing_mode", "false"
|
buildConfigField "boolean", "surfing_mode", "false"
|
||||||
buildConfigField "boolean", "sepia_search", "false"
|
buildConfigField "boolean", "sepia_search", "false"
|
||||||
buildConfigField "boolean", "instance_switcher", "true"
|
buildConfigField "boolean", "instance_switcher", "true"
|
||||||
|
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||||
}
|
}
|
||||||
fdroid_full {
|
fdroid_full {
|
||||||
applicationId "app.fedilab.tubelab"
|
applicationId "app.fedilab.tubelab"
|
||||||
|
@ -72,6 +74,7 @@ android {
|
||||||
buildConfigField "boolean", "surfing_mode", "true"
|
buildConfigField "boolean", "surfing_mode", "true"
|
||||||
buildConfigField "boolean", "sepia_search", "true"
|
buildConfigField "boolean", "sepia_search", "true"
|
||||||
buildConfigField "boolean", "instance_switcher", "true"
|
buildConfigField "boolean", "instance_switcher", "true"
|
||||||
|
buildConfigField "boolean", "allow_remote_connections", "true"
|
||||||
}
|
}
|
||||||
google_full {
|
google_full {
|
||||||
applicationId "app.fedilab.tubelab"
|
applicationId "app.fedilab.tubelab"
|
||||||
|
@ -83,6 +86,7 @@ android {
|
||||||
buildConfigField "boolean", "surfing_mode", "true"
|
buildConfigField "boolean", "surfing_mode", "true"
|
||||||
buildConfigField "boolean", "sepia_search", "true"
|
buildConfigField "boolean", "sepia_search", "true"
|
||||||
buildConfigField "boolean", "instance_switcher", "true"
|
buildConfigField "boolean", "instance_switcher", "true"
|
||||||
|
buildConfigField "boolean", "allow_remote_connections", "true"
|
||||||
}
|
}
|
||||||
queermotion {
|
queermotion {
|
||||||
applicationId "org.queermotion.peertube"
|
applicationId "org.queermotion.peertube"
|
||||||
|
@ -94,6 +98,7 @@ android {
|
||||||
buildConfigField "boolean", "surfing_mode", "false"
|
buildConfigField "boolean", "surfing_mode", "false"
|
||||||
buildConfigField "boolean", "sepia_search", "false"
|
buildConfigField "boolean", "sepia_search", "false"
|
||||||
buildConfigField "boolean", "instance_switcher", "false"
|
buildConfigField "boolean", "instance_switcher", "false"
|
||||||
|
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||||
}
|
}
|
||||||
bittube {
|
bittube {
|
||||||
applicationId "app.fedilab.bittube"
|
applicationId "app.fedilab.bittube"
|
||||||
|
@ -105,7 +110,7 @@ android {
|
||||||
buildConfigField "boolean", "surfing_mode", "false"
|
buildConfigField "boolean", "surfing_mode", "false"
|
||||||
buildConfigField "boolean", "sepia_search", "false"
|
buildConfigField "boolean", "sepia_search", "false"
|
||||||
buildConfigField "boolean", "instance_switcher", "true"
|
buildConfigField "boolean", "instance_switcher", "true"
|
||||||
|
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,13 @@ import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import app.fedilab.fedilabtube.client.RetrofitMastodonAPI;
|
||||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||||
import app.fedilab.fedilabtube.client.entities.Error;
|
import app.fedilab.fedilabtube.client.entities.Error;
|
||||||
import app.fedilab.fedilabtube.client.entities.Oauth;
|
import app.fedilab.fedilabtube.client.entities.Oauth;
|
||||||
import app.fedilab.fedilabtube.client.entities.OauthParams;
|
import app.fedilab.fedilabtube.client.entities.OauthParams;
|
||||||
import app.fedilab.fedilabtube.client.entities.Token;
|
import app.fedilab.fedilabtube.client.entities.Token;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.WellKnownNodeinfo;
|
||||||
import app.fedilab.fedilabtube.databinding.ActivityLoginBinding;
|
import app.fedilab.fedilabtube.databinding.ActivityLoginBinding;
|
||||||
import app.fedilab.fedilabtube.helper.Helper;
|
import app.fedilab.fedilabtube.helper.Helper;
|
||||||
import app.fedilab.fedilabtube.helper.HelperAcadInstance;
|
import app.fedilab.fedilabtube.helper.HelperAcadInstance;
|
||||||
|
@ -76,6 +78,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
SpannableString content_create;
|
SpannableString content_create;
|
||||||
|
//noinspection ConstantConditions
|
||||||
if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) {
|
if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) {
|
||||||
content_create = new SpannableString(getString(R.string.register_account));
|
content_create = new SpannableString(getString(R.string.register_account));
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,6 +101,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
if (BuildConfig.full_instances && BuildConfig.instance_switcher) {
|
if (BuildConfig.full_instances && BuildConfig.instance_switcher) {
|
||||||
binding.loginInstanceContainer.setVisibility(View.VISIBLE);
|
binding.loginInstanceContainer.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
//noinspection ConstantConditions
|
||||||
if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) {
|
if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) {
|
||||||
binding.loginInstance.setText("queermotion.org");
|
binding.loginInstance.setText("queermotion.org");
|
||||||
}
|
}
|
||||||
|
@ -211,7 +215,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
binding.loginButton.setEnabled(false);
|
binding.loginButton.setEnabled(false);
|
||||||
String instance, host;
|
String instance;
|
||||||
if (!BuildConfig.full_instances) {
|
if (!BuildConfig.full_instances) {
|
||||||
String[] emailArray = binding.loginUid.getText().toString().split("@");
|
String[] emailArray = binding.loginUid.getText().toString().split("@");
|
||||||
if (emailArray.length > 1 && !Arrays.asList(HelperAcadInstance.valideEmails).contains(emailArray[1])) {
|
if (emailArray.length > 1 && !Arrays.asList(HelperAcadInstance.valideEmails).contains(emailArray[1])) {
|
||||||
|
@ -221,21 +225,19 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
instance = HelperInstance.getLiveInstance(LoginActivity.this);
|
instance = HelperInstance.getLiveInstance(LoginActivity.this);
|
||||||
host = instance;
|
|
||||||
} else {
|
} else {
|
||||||
if (binding.loginInstance.getText() == null || binding.loginInstance.getText().toString().trim().length() == 0) {
|
if (binding.loginInstance.getText() == null || binding.loginInstance.getText().toString().trim().length() == 0) {
|
||||||
Toasty.error(LoginActivity.this, getString(R.string.not_valide_instance)).show();
|
Toasty.error(LoginActivity.this, getString(R.string.not_valide_instance)).show();
|
||||||
binding.loginButton.setEnabled(true);
|
binding.loginButton.setEnabled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instance = host = binding.loginInstance.getText().toString().trim().toLowerCase();
|
instance = binding.loginInstance.getText().toString().trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance.startsWith("http")) {
|
if (instance.startsWith("http")) {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(instance);
|
URL url = new URL(instance);
|
||||||
instance = url.getHost();
|
instance = url.getHost();
|
||||||
host = instance;
|
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -243,7 +245,6 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
try {
|
try {
|
||||||
URL url = new URL("https://" + instance);
|
URL url = new URL("https://" + instance);
|
||||||
instance = url.getHost();
|
instance = url.getHost();
|
||||||
host = instance;
|
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -254,57 +255,133 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String finalInstance = instance;
|
String finalInstance = instance;
|
||||||
String finalHost = host;
|
|
||||||
if (BuildConfig.full_instances) {
|
if (BuildConfig.full_instances) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.WEBSITE_VALUE, Helper.OAUTH_SCOPES_PEERTUBE, Helper.WEBSITE_VALUE);
|
boolean connectAPeertubeAccount = true;
|
||||||
if (oauth == null) {
|
WellKnownNodeinfo.NodeInfo instanceNodeInfo = null;
|
||||||
runOnUiThread(() -> {
|
if (BuildConfig.allow_remote_connections) {
|
||||||
binding.loginButton.setEnabled(true);
|
instanceNodeInfo = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).getNodeInfo();
|
||||||
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
|
if (instanceNodeInfo != null && instanceNodeInfo.getSoftware().getName().toUpperCase().trim().compareTo("PEERTUBE") != 0) {
|
||||||
});
|
connectAPeertubeAccount = false;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_id = oauth.getClient_id();
|
|
||||||
client_secret = oauth.getClient_secret();
|
|
||||||
|
|
||||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
|
||||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
||||||
editor.putString(Helper.CLIENT_ID, client_id);
|
|
||||||
editor.putString(Helper.CLIENT_SECRET, client_secret);
|
|
||||||
editor.apply();
|
|
||||||
OauthParams oauthParams = new OauthParams();
|
|
||||||
oauthParams.setClient_id(client_id);
|
|
||||||
oauthParams.setClient_secret(client_secret);
|
|
||||||
oauthParams.setGrant_type("password");
|
|
||||||
oauthParams.setScope("user");
|
|
||||||
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
|
|
||||||
if (binding.loginPasswd.getText() != null) {
|
|
||||||
oauthParams.setPassword(binding.loginPasswd.getText().toString());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
|
||||||
proceedLogin(token, finalHost);
|
|
||||||
} catch (final Exception | Error e) {
|
|
||||||
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
|
|
||||||
try {
|
|
||||||
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
|
||||||
proceedLogin(token, finalHost);
|
|
||||||
} catch (Error error) {
|
|
||||||
Error.displayError(LoginActivity.this, error);
|
|
||||||
error.printStackTrace();
|
|
||||||
runOnUiThread(() -> binding.loginButton.setEnabled(true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (connectAPeertubeAccount) {
|
||||||
|
connectToPeertube(finalInstance);
|
||||||
|
} else {
|
||||||
|
connectToFediverse(finalInstance, instanceNodeInfo);
|
||||||
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void connectToFediverse(String finalInstance, WellKnownNodeinfo.NodeInfo instanceNodeInfo) {
|
||||||
|
switch (instanceNodeInfo.getSoftware().getName().toUpperCase().trim()) {
|
||||||
|
case "MASTODON":
|
||||||
|
case "PLEROMA":
|
||||||
|
Oauth oauth = new RetrofitMastodonAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.REDIRECT_CONTENT, Helper.OAUTH_SCOPES_MASTODON, Helper.WEBSITE_VALUE);
|
||||||
|
if (oauth == null) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
binding.loginButton.setEnabled(true);
|
||||||
|
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client_id = oauth.getClient_id();
|
||||||
|
client_secret = oauth.getClient_secret();
|
||||||
|
|
||||||
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putString(Helper.CLIENT_ID, client_id);
|
||||||
|
editor.putString(Helper.CLIENT_SECRET, client_secret);
|
||||||
|
editor.apply();
|
||||||
|
OauthParams oauthParams = new OauthParams();
|
||||||
|
oauthParams.setClient_id(client_id);
|
||||||
|
oauthParams.setClient_secret(client_secret);
|
||||||
|
oauthParams.setGrant_type("password");
|
||||||
|
oauthParams.setScope("user");
|
||||||
|
if (binding.loginUid.getText() != null) {
|
||||||
|
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
|
||||||
|
}
|
||||||
|
if (binding.loginPasswd.getText() != null) {
|
||||||
|
oauthParams.setPassword(binding.loginPasswd.getText().toString());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Token token = new RetrofitMastodonAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
||||||
|
proceedLogin(token, finalInstance, instanceNodeInfo.getSoftware().getName().toUpperCase().trim());
|
||||||
|
} catch (final Exception | Error e) {
|
||||||
|
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
|
||||||
|
try {
|
||||||
|
Token token = new RetrofitMastodonAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
||||||
|
proceedLogin(token, finalInstance, instanceNodeInfo.getSoftware().getName().toUpperCase().trim());
|
||||||
|
} catch (Error error) {
|
||||||
|
Error.displayError(LoginActivity.this, error);
|
||||||
|
error.printStackTrace();
|
||||||
|
runOnUiThread(() -> binding.loginButton.setEnabled(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "FRIENDICA":
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oauth process for Peertube
|
||||||
|
*
|
||||||
|
* @param finalInstance String
|
||||||
|
*/
|
||||||
|
private void connectToPeertube(String finalInstance) {
|
||||||
|
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.WEBSITE_VALUE, Helper.OAUTH_SCOPES_PEERTUBE, Helper.WEBSITE_VALUE);
|
||||||
|
if (oauth == null) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
binding.loginButton.setEnabled(true);
|
||||||
|
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_id = oauth.getClient_id();
|
||||||
|
client_secret = oauth.getClient_secret();
|
||||||
|
|
||||||
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putString(Helper.CLIENT_ID, client_id);
|
||||||
|
editor.putString(Helper.CLIENT_SECRET, client_secret);
|
||||||
|
editor.apply();
|
||||||
|
OauthParams oauthParams = new OauthParams();
|
||||||
|
oauthParams.setClient_id(client_id);
|
||||||
|
oauthParams.setClient_secret(client_secret);
|
||||||
|
oauthParams.setGrant_type("password");
|
||||||
|
oauthParams.setScope("user");
|
||||||
|
if (binding.loginUid.getText() != null) {
|
||||||
|
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
|
||||||
|
}
|
||||||
|
if (binding.loginPasswd.getText() != null) {
|
||||||
|
oauthParams.setPassword(binding.loginPasswd.getText().toString());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
||||||
|
proceedLogin(token, finalInstance, null);
|
||||||
|
} catch (final Exception | Error e) {
|
||||||
|
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
|
||||||
|
try {
|
||||||
|
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
||||||
|
proceedLogin(token, finalInstance, null);
|
||||||
|
} catch (Error error) {
|
||||||
|
Error.displayError(LoginActivity.this, error);
|
||||||
|
error.printStackTrace();
|
||||||
|
runOnUiThread(() -> binding.loginButton.setEnabled(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("ApplySharedPref")
|
@SuppressLint("ApplySharedPref")
|
||||||
private void proceedLogin(Token token, String host) {
|
private void proceedLogin(Token token, String host, String software) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||||
|
@ -313,7 +390,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
editor.putString(Helper.PREF_INSTANCE, host);
|
editor.putString(Helper.PREF_INSTANCE, host);
|
||||||
editor.commit();
|
editor.commit();
|
||||||
//Update the account with the token;
|
//Update the account with the token;
|
||||||
updateCredential(LoginActivity.this, token.getAccess_token(), client_id, client_secret, token.getRefresh_token(), host);
|
updateCredential(LoginActivity.this, token.getAccess_token(), client_id, client_secret, token.getRefresh_token(), host, software);
|
||||||
} else {
|
} else {
|
||||||
binding.loginButton.setEnabled(true);
|
binding.loginButton.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package app.fedilab.fedilabtube.client;
|
||||||
|
/* Copyright 2020 Thomas Schneider
|
||||||
|
*
|
||||||
|
* This file is a part of TubeLab
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||||
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||||
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
|
|
||||||
|
import app.fedilab.fedilabtube.client.data.AccountData;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.Oauth;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.Token;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.Field;
|
||||||
|
import retrofit2.http.FormUrlEncoded;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Header;
|
||||||
|
import retrofit2.http.POST;
|
||||||
|
import retrofit2.http.Query;
|
||||||
|
|
||||||
|
interface MastodonService {
|
||||||
|
|
||||||
|
@GET("apps")
|
||||||
|
Call<Oauth> getOauth(@Query("client_name") String client_name, @Query("redirect_uris") String redirect_uris, @Query("scopes") String scopes, @Query("website") String website);
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/oauth/token")
|
||||||
|
Call<Token> createToken(
|
||||||
|
@Field("client_id") String client_id,
|
||||||
|
@Field("client_secret") String client_secret,
|
||||||
|
@Field("grant_type") String grant_type,
|
||||||
|
@Field("scrope") String scope,
|
||||||
|
@Field("username") String username,
|
||||||
|
@Field("password") String password);
|
||||||
|
|
||||||
|
@GET("/accounts/verify_credentials")
|
||||||
|
Call<AccountData.Account> verifyCredentials(@Header("Authorization") String credentials);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
package app.fedilab.fedilabtube.client;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
|
||||||
|
import app.fedilab.fedilabtube.BuildConfig;
|
||||||
|
import app.fedilab.fedilabtube.MainActivity;
|
||||||
|
import app.fedilab.fedilabtube.R;
|
||||||
|
import app.fedilab.fedilabtube.client.data.AccountData;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.Error;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.Oauth;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.OauthParams;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.Token;
|
||||||
|
import app.fedilab.fedilabtube.client.entities.UserMe;
|
||||||
|
import app.fedilab.fedilabtube.helper.Helper;
|
||||||
|
import app.fedilab.fedilabtube.helper.HelperInstance;
|
||||||
|
import app.fedilab.fedilabtube.sqlite.AccountDAO;
|
||||||
|
import app.fedilab.fedilabtube.sqlite.Sqlite;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Response;
|
||||||
|
import retrofit2.Retrofit;
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory;
|
||||||
|
|
||||||
|
public class RetrofitMastodonAPI {
|
||||||
|
|
||||||
|
private final String finalUrl;
|
||||||
|
private final Context _context;
|
||||||
|
private final String instance;
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public RetrofitMastodonAPI(Context context) {
|
||||||
|
_context = context;
|
||||||
|
instance = HelperInstance.getLiveInstance(context);
|
||||||
|
finalUrl = "https://" + HelperInstance.getLiveInstance(context) + "/api/v1/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public RetrofitMastodonAPI(Context context, String instance, String token) {
|
||||||
|
_context = context;
|
||||||
|
this.instance = instance;
|
||||||
|
this.token = token;
|
||||||
|
finalUrl = "https://" + instance + "/api/v1/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host, String software) {
|
||||||
|
new Thread(() -> {
|
||||||
|
AccountData.Account account;
|
||||||
|
String instance = host;
|
||||||
|
try {
|
||||||
|
account = new RetrofitMastodonAPI(activity, instance, token).verifyCredentials();
|
||||||
|
} catch (Error error) {
|
||||||
|
Error.displayError(activity, error);
|
||||||
|
error.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
//At the state the instance can be encoded
|
||||||
|
instance = URLDecoder.decode(instance, "utf-8");
|
||||||
|
} catch (UnsupportedEncodingException ignored) {
|
||||||
|
}
|
||||||
|
SharedPreferences sharedpreferences = activity.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
account.setToken(token);
|
||||||
|
account.setClient_id(client_id);
|
||||||
|
account.setClient_secret(client_secret);
|
||||||
|
account.setRefresh_token(refresh_token);
|
||||||
|
account.setHost(instance);
|
||||||
|
SQLiteDatabase db = Sqlite.getInstance(activity.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||||
|
boolean userExists = new AccountDAO(activity, db).userExist(account);
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putString(Helper.PREF_KEY_ID, account.getId());
|
||||||
|
editor.putString(Helper.PREF_KEY_NAME, account.getUsername());
|
||||||
|
editor.apply();
|
||||||
|
if (userExists)
|
||||||
|
new AccountDAO(activity, db).updateAccountCredential(account);
|
||||||
|
else {
|
||||||
|
if (account.getUsername() != null && account.getCreatedAt() != null)
|
||||||
|
new AccountDAO(activity, db).insertAccount(account, software);
|
||||||
|
}
|
||||||
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
|
Runnable myRunnable = () -> {
|
||||||
|
Intent mainActivity = new Intent(activity, MainActivity.class);
|
||||||
|
mainActivity.putExtra(Helper.INTENT_ACTION, Helper.ADD_USER_INTENT);
|
||||||
|
activity.startActivity(mainActivity);
|
||||||
|
activity.finish();
|
||||||
|
};
|
||||||
|
mainHandler.post(myRunnable);
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MastodonService init() {
|
||||||
|
Retrofit retrofit = new Retrofit.Builder()
|
||||||
|
.baseUrl(finalUrl)
|
||||||
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
|
.build();
|
||||||
|
SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
if (token == null) {
|
||||||
|
token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||||
|
}
|
||||||
|
return retrofit.create(MastodonService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Oauth
|
||||||
|
*
|
||||||
|
* @return APIResponse
|
||||||
|
*/
|
||||||
|
public Oauth oauthClient(String client_name, String redirect_uris, String scopes, String website) {
|
||||||
|
MastodonService mastodonService = init();
|
||||||
|
try {
|
||||||
|
Call<Oauth> oauth;
|
||||||
|
oauth = mastodonService.getOauth(client_name, redirect_uris, scopes, website);
|
||||||
|
Response<Oauth> response = oauth.execute();
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
return response.body();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Verifiy credential of the authenticated user *synchronously*
|
||||||
|
* @return Account
|
||||||
|
*/
|
||||||
|
public AccountData.Account verifyCredentials() throws Error {
|
||||||
|
MastodonService mastodonService = init();
|
||||||
|
Call<AccountData.Account> accountCall = mastodonService.verifyCredentials("Bearer " + token);
|
||||||
|
APIResponse apiResponse = new APIResponse();
|
||||||
|
try {
|
||||||
|
Response<AccountData.Account> response = accountCall.execute();
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
return response.body();
|
||||||
|
} else {
|
||||||
|
Error error = new Error();
|
||||||
|
error.setStatusCode(response.code());
|
||||||
|
if (response.errorBody() != null) {
|
||||||
|
error.setError(response.errorBody().string());
|
||||||
|
} else {
|
||||||
|
error.setError(_context.getString(R.string.toast_error));
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Error error = new Error();
|
||||||
|
error.setError(_context.getString(R.string.toast_error));
|
||||||
|
apiResponse.setError(error);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Verifiy credential of the authenticated user *synchronously*
|
||||||
|
* @return Account
|
||||||
|
*/
|
||||||
|
public Token manageToken(OauthParams oauthParams) throws Error {
|
||||||
|
MastodonService mastodonService = init();
|
||||||
|
Call<Token> createToken = mastodonService.createToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getGrant_type(), oauthParams.getScope(), oauthParams.getUsername(), oauthParams.getPassword());
|
||||||
|
if (createToken != null) {
|
||||||
|
try {
|
||||||
|
Response<Token> response = createToken.execute();
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
return response.body();
|
||||||
|
} else {
|
||||||
|
Error error = new Error();
|
||||||
|
error.setStatusCode(response.code());
|
||||||
|
if (response.errorBody() != null) {
|
||||||
|
error.setError(response.errorBody().string());
|
||||||
|
} else {
|
||||||
|
error.setError(_context.getString(R.string.toast_error));
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,7 +101,7 @@ public class RetrofitPeertubeAPI {
|
||||||
private final String count;
|
private final String count;
|
||||||
private String token;
|
private String token;
|
||||||
private Set<String> selection;
|
private Set<String> selection;
|
||||||
private String showNSFWVideos = "both";
|
private final String showNSFWVideos;
|
||||||
|
|
||||||
public RetrofitPeertubeAPI(Context context) {
|
public RetrofitPeertubeAPI(Context context) {
|
||||||
_context = context;
|
_context = context;
|
||||||
|
@ -137,7 +137,7 @@ public class RetrofitPeertubeAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host) {
|
public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host, String software) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
AccountData.Account account;
|
AccountData.Account account;
|
||||||
String instance = host;
|
String instance = host;
|
||||||
|
@ -173,7 +173,7 @@ public class RetrofitPeertubeAPI {
|
||||||
new AccountDAO(activity, db).updateAccountCredential(account);
|
new AccountDAO(activity, db).updateAccountCredential(account);
|
||||||
else {
|
else {
|
||||||
if (account.getUsername() != null && account.getCreatedAt() != null)
|
if (account.getUsername() != null && account.getCreatedAt() != null)
|
||||||
new AccountDAO(activity, db).insertAccount(account);
|
new AccountDAO(activity, db).insertAccount(account, software);
|
||||||
}
|
}
|
||||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
Runnable myRunnable = () -> {
|
Runnable myRunnable = () -> {
|
||||||
|
|
|
@ -111,6 +111,8 @@ public class Helper {
|
||||||
public static final String WEBSITE_VALUE = "https://fedilab.app";
|
public static final String WEBSITE_VALUE = "https://fedilab.app";
|
||||||
public static final String CLIENT_NAME_VALUE = "TubeLab";
|
public static final String CLIENT_NAME_VALUE = "TubeLab";
|
||||||
public static final String OAUTH_SCOPES_PEERTUBE = "openid profile";
|
public static final String OAUTH_SCOPES_PEERTUBE = "openid profile";
|
||||||
|
public static final String OAUTH_SCOPES_MASTODON = "read write follow";
|
||||||
|
public static final String REDIRECT_CONTENT = "urn:ietf:wg:oauth:2.0:oob";
|
||||||
public static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
|
public static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
|
||||||
public static final Pattern redirectPattern = Pattern.compile("externalAuthToken=(\\w+)&username=([\\w.-]+)");
|
public static final Pattern redirectPattern = Pattern.compile("externalAuthToken=(\\w+)&username=([\\w.-]+)");
|
||||||
public static final String SET_VIDEO_CACHE = "set_video_cache";
|
public static final String SET_VIDEO_CACHE = "set_video_cache";
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class AccountDAO {
|
||||||
* @param account Account
|
* @param account Account
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public boolean insertAccount(Account account) {
|
public boolean insertAccount(Account account, String software) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
if (account.getCreatedAt() == null)
|
if (account.getCreatedAt() == null)
|
||||||
account.setCreatedAt(new Date());
|
account.setCreatedAt(new Date());
|
||||||
|
@ -74,6 +74,9 @@ public class AccountDAO {
|
||||||
values.put(Sqlite.COL_AVATAR_STATIC, "");
|
values.put(Sqlite.COL_AVATAR_STATIC, "");
|
||||||
values.put(Sqlite.COL_HEADER, "");
|
values.put(Sqlite.COL_HEADER, "");
|
||||||
values.put(Sqlite.COL_HEADER_STATIC, "");
|
values.put(Sqlite.COL_HEADER_STATIC, "");
|
||||||
|
if (software != null && software.toUpperCase().trim().compareTo("PEERTUBE") != 0) {
|
||||||
|
values.put(Sqlite.COL_SOFTWARE, software.toUpperCase().trim());
|
||||||
|
}
|
||||||
if (account.getClient_id() != null && account.getClient_secret() != null) {
|
if (account.getClient_id() != null && account.getClient_secret() != null) {
|
||||||
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
|
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
|
||||||
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());
|
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());
|
||||||
|
|
|
@ -15,13 +15,19 @@ package app.fedilab.fedilabtube.sqlite;
|
||||||
* see <http://www.gnu.org/licenses>. */
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
public class Sqlite extends SQLiteOpenHelper {
|
public class Sqlite extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public static final int DB_VERSION = 3;
|
public static final int DB_VERSION = 4;
|
||||||
public static final String DB_NAME = "mastodon_etalab_db";
|
public static final String DB_NAME = "mastodon_etalab_db";
|
||||||
/***
|
/***
|
||||||
* List of tables to manage users and data
|
* List of tables to manage users and data
|
||||||
|
@ -67,6 +73,7 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
static final String TABLE_VIDEOS = "VIDEOS";
|
static final String TABLE_VIDEOS = "VIDEOS";
|
||||||
static final String COL_VIDEO_DATA = "VIDEO_DATA";
|
static final String COL_VIDEO_DATA = "VIDEO_DATA";
|
||||||
static final String COL_PLAYLIST_ID = "PLAYLIST_ID";
|
static final String COL_PLAYLIST_ID = "PLAYLIST_ID";
|
||||||
|
static final String COL_SOFTWARE = "SOFTWARE";
|
||||||
private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " ("
|
private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " ("
|
||||||
+ COL_USER_ID + " TEXT, " + COL_USERNAME + " TEXT NOT NULL, " + COL_ACCT + " TEXT NOT NULL, "
|
+ COL_USER_ID + " TEXT, " + COL_USERNAME + " TEXT NOT NULL, " + COL_ACCT + " TEXT NOT NULL, "
|
||||||
+ COL_DISPLAYED_NAME + " TEXT NOT NULL, " + COL_LOCKED + " INTEGER NOT NULL, "
|
+ COL_DISPLAYED_NAME + " TEXT NOT NULL, " + COL_LOCKED + " INTEGER NOT NULL, "
|
||||||
|
@ -79,8 +86,11 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
+ COL_CLIENT_ID + " TEXT, " + COL_CLIENT_SECRET + " TEXT, " + COL_REFRESH_TOKEN + " TEXT,"
|
+ COL_CLIENT_ID + " TEXT, " + COL_CLIENT_SECRET + " TEXT, " + COL_REFRESH_TOKEN + " TEXT,"
|
||||||
+ COL_UPDATED_AT + " TEXT, "
|
+ COL_UPDATED_AT + " TEXT, "
|
||||||
+ COL_PRIVACY + " TEXT, "
|
+ COL_PRIVACY + " TEXT, "
|
||||||
|
+ COL_SOFTWARE + " TEXT NOT NULL DEFAULT \"PEERTUBE\", "
|
||||||
+ COL_SENSITIVE + " INTEGER DEFAULT 0, "
|
+ COL_SENSITIVE + " INTEGER DEFAULT 0, "
|
||||||
+ COL_INSTANCE + " TEXT NOT NULL, " + COL_OAUTHTOKEN + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL)";
|
+ COL_INSTANCE + " TEXT NOT NULL, " + COL_OAUTHTOKEN + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL)";
|
||||||
|
|
||||||
|
|
||||||
public static SQLiteDatabase db;
|
public static SQLiteDatabase db;
|
||||||
private static Sqlite sInstance;
|
private static Sqlite sInstance;
|
||||||
private final String CREATE_TABLE_PEERTUBE_FAVOURITES = "CREATE TABLE "
|
private final String CREATE_TABLE_PEERTUBE_FAVOURITES = "CREATE TABLE "
|
||||||
|
@ -136,15 +146,44 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
@Override
|
@Override
|
||||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
switch (oldVersion) {
|
switch (oldVersion) {
|
||||||
|
case 4:
|
||||||
|
dropColumn(TABLE_USER_ACCOUNT, new String[]{COL_SOFTWARE});
|
||||||
case 3:
|
case 3:
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_VIDEOS);
|
db.execSQL("DROP TABLE IF EXISTS " + TABLE_VIDEOS);
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOCAL_PLAYLISTS);
|
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOCAL_PLAYLISTS);
|
||||||
case 2:
|
case 2:
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_BOOKMARKED_INSTANCES);
|
db.execSQL("DROP TABLE IF EXISTS " + TABLE_BOOKMARKED_INSTANCES);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
|
private void dropColumn(
|
||||||
|
String tableName,
|
||||||
|
String[] colsToRemove) {
|
||||||
|
List<String> updatedTableColumns = getTableColumns(tableName);
|
||||||
|
// Remove the columns we don't want anymore from the table's list of columns
|
||||||
|
updatedTableColumns.removeAll(Arrays.asList(colsToRemove));
|
||||||
|
String columnsSeperated = TextUtils.join(",", updatedTableColumns);
|
||||||
|
db.execSQL("ALTER TABLE " + tableName + " RENAME TO " + tableName + "_old;");
|
||||||
|
// Creating the table on its new format (no redundant columns)
|
||||||
|
db.execSQL("CREATE TABLE " + tableName);
|
||||||
|
// Populating the table with the data
|
||||||
|
db.execSQL("INSERT INTO " + tableName + "(" + columnsSeperated + ") SELECT "
|
||||||
|
+ columnsSeperated + " FROM " + tableName + "_old;");
|
||||||
|
db.execSQL("DROP TABLE " + tableName + "_old;");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTableColumns(String tableName) {
|
||||||
|
ArrayList<String> columns = new ArrayList<>();
|
||||||
|
String cmd = "pragma table_info(" + tableName + ");";
|
||||||
|
Cursor cur = db.rawQuery(cmd, null);
|
||||||
|
while (cur.moveToNext()) {
|
||||||
|
columns.add(cur.getString(cur.getColumnIndex("name")));
|
||||||
|
}
|
||||||
|
cur.close();
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
switch (oldVersion) {
|
switch (oldVersion) {
|
||||||
|
@ -153,6 +192,8 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
case 2:
|
case 2:
|
||||||
db.execSQL(CREATE_TABLE_LOCAL_PLAYLISTS);
|
db.execSQL(CREATE_TABLE_LOCAL_PLAYLISTS);
|
||||||
db.execSQL(CREATE_TABLE_VIDEOS);
|
db.execSQL(CREATE_TABLE_VIDEOS);
|
||||||
|
case 3:
|
||||||
|
db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_SOFTWARE + " TEXT NOT NULL DEFAULT \"PEERTUBE\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue