Add authentication #689

This commit is contained in:
stom79 2019-01-02 19:39:40 +01:00
parent 6b623e96bf
commit eebe401aaf
10 changed files with 4024 additions and 21 deletions

View File

@ -91,6 +91,9 @@ public class LoginActivity extends BaseActivity {
boolean isLoadingInstance = false;
private String oldSearch;
private ImageView info_uid, info_instance, info_pwd, info_2FA;
private CheckBox peertube_instance;
private Button connectionButton;
private String actionToken;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -122,7 +125,7 @@ public class LoginActivity extends BaseActivity {
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
editor.apply();
//Update the account with the token;
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, instance, peertube_instance.isChecked()?UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE:UpdateAccountInfoAsyncTask.SOCIAL.MASTODON).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (JSONException ignored) {}
} catch (Exception ignored) {}
}}).start();
@ -171,7 +174,7 @@ public class LoginActivity extends BaseActivity {
} else {
changeDrawableColor(getApplicationContext(), R.drawable.mastodon_icon, R.color.mastodonC3);
}
final Button connectionButton = findViewById(R.id.login_button);
login_instance = findViewById(R.id.login_instance);
login_uid = findViewById(R.id.login_uid);
login_passwd = findViewById(R.id.login_passwd);
@ -179,6 +182,8 @@ public class LoginActivity extends BaseActivity {
info_instance = findViewById(R.id.info_instance);
info_pwd = findViewById(R.id.info_pwd);
info_2FA = findViewById(R.id.info_2FA);
peertube_instance = findViewById(R.id.peertube_instance);
connectionButton = findViewById(R.id.login_button);
info_instance.setOnClickListener(new View.OnClickListener() {
@Override
@ -309,6 +314,7 @@ public class LoginActivity extends BaseActivity {
startActivity(browserIntent);
}
});
login_instance.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
@ -369,7 +375,7 @@ public class LoginActivity extends BaseActivity {
@Override
protected void onResume(){
super.onResume();
Button connectionButton = findViewById(R.id.login_button);
if (login_instance != null &&login_instance.getText() != null && login_instance.getText().toString().length() > 0 && client_id_for_webview) {
connectionButton.setEnabled(false);
client_id_for_webview = false;
@ -378,24 +384,35 @@ public class LoginActivity extends BaseActivity {
}
private void retrievesClientId(){
final Button connectionButton = findViewById(R.id.login_button);
try {
instance = URLEncoder.encode(login_instance.getText().toString().trim(), "utf-8");
} catch (UnsupportedEncodingException e) {
Toasty.error(LoginActivity.this,getString(R.string.client_error), Toast.LENGTH_LONG).show();
}
final String action = "/api/v1/apps";
if( !peertube_instance.isChecked())
actionToken = "/api/v1/apps";
else
actionToken = "/api/v1/oauth-clients/local";
final HashMap<String, String> parameters = new HashMap<>();
parameters.put(Helper.CLIENT_NAME, Helper.CLIENT_NAME_VALUE);
parameters.put(Helper.REDIRECT_URIS, client_id_for_webview?Helper.REDIRECT_CONTENT_WEB:Helper.REDIRECT_CONTENT);
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES);
if( !peertube_instance.isChecked()) {
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES);
}else {
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES_PEERTUBE);
}
parameters.put(Helper.WEBSITE, Helper.WEBSITE_VALUE);
new Thread(new Runnable(){
@Override
public void run() {
try {
final String response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + action, 30, parameters, null );
String response;
if( !peertube_instance.isChecked())
response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + actionToken, 30, parameters, null );
else
response = new HttpsConnection(LoginActivity.this).get(Helper.instanceWithProtocol(instance) + actionToken, 30, parameters, null );
runOnUiThread(new Runnable() {
public void run() {
JSONObject resobj;
@ -403,7 +420,9 @@ public class LoginActivity extends BaseActivity {
resobj = new JSONObject(response);
client_id = resobj.get(Helper.CLIENT_ID).toString();
client_secret = resobj.get(Helper.CLIENT_SECRET).toString();
String id = resobj.get(Helper.ID).toString();
String id = null;
if( !peertube_instance.isChecked())
id = resobj.get(Helper.ID).toString();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.CLIENT_ID, client_id);
@ -418,6 +437,7 @@ public class LoginActivity extends BaseActivity {
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
if( embedded_browser) {
Intent i = new Intent(LoginActivity.this, WebviewConnectActivity.class);
i.putExtra("social", peertube_instance.isChecked()?UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE:UpdateAccountInfoAsyncTask.SOCIAL.MASTODON);
i.putExtra("instance", instance);
startActivity(i);
}else{
@ -471,13 +491,19 @@ public class LoginActivity extends BaseActivity {
} catch (UnsupportedEncodingException e) {
parameters.put("password",login_passwd.getText().toString());
}
parameters.put("scope"," read write follow");
String oauthUrl;
if( !peertube_instance.isChecked()) {
parameters.put("scope", " read write follow");
oauthUrl = "/oauth/token";
}else {
parameters.put("scope", "user");
oauthUrl = "/api/v1/users/token";
}
new Thread(new Runnable(){
@Override
public void run() {
try {
final String response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + "/oauth/token", 30, parameters, null );
final String response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + oauthUrl, 30, parameters, null );
runOnUiThread(new Runnable() {
public void run() {
JSONObject resobj;
@ -489,7 +515,7 @@ public class LoginActivity extends BaseActivity {
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
editor.apply();
//Update the account with the token;
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, instance, peertube_instance.isChecked()?UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE:UpdateAccountInfoAsyncTask.SOCIAL.MASTODON).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (JSONException ignored) {ignored.printStackTrace();}
}
});

View File

@ -63,6 +63,7 @@ public class WebviewConnectActivity extends BaseActivity {
private AlertDialog alert;
private String clientId, clientSecret;
private String instance;
private UpdateAccountInfoAsyncTask.SOCIAL social;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -84,8 +85,10 @@ public class WebviewConnectActivity extends BaseActivity {
setContentView(R.layout.activity_webview_connect);
Bundle b = getIntent().getExtras();
if(b != null)
if(b != null) {
instance = b.getString("instance");
social = (UpdateAccountInfoAsyncTask.SOCIAL) b.getSerializable("social");
}
if( instance == null)
finish();
clientId = sharedpreferences.getString(Helper.CLIENT_ID, null);
@ -167,7 +170,7 @@ public class WebviewConnectActivity extends BaseActivity {
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
editor.apply();
//Update the account with the token;
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, instance, social).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (JSONException ignored) {}
} catch (Exception ignored) {}
}}).start();

View File

@ -28,9 +28,10 @@ import java.net.URLDecoder;
import fr.gouv.etalab.mastodon.activities.MainActivity;
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
/**
* Created by Thomas on 23/04/2017.
@ -42,16 +43,30 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask<Void, Void, Void> {
private String token;
private String instance;
private WeakReference<Context> contextReference;
private SOCIAL social;
public UpdateAccountInfoAsyncTask(Context context, String token, String instance){
public enum SOCIAL{
MASTODON,
PEERTUBE
}
public UpdateAccountInfoAsyncTask(Context context, String token, String instance, SOCIAL social){
this.contextReference = new WeakReference<>(context);
this.token = token;
this.instance = instance;
this.social = social;
}
@Override
protected Void doInBackground(Void... params) {
Account account = new API(this.contextReference.get(), instance, null).verifyCredentials();
Account account = null;
if( social == SOCIAL.MASTODON)
account = new API(this.contextReference.get(), instance, null).verifyCredentials();
else if( social == SOCIAL.PEERTUBE)
account = new PeertubeAPI(this.contextReference.get(), instance, null).verifyCredentials();
if( account == null)
return null;
try {
//At the state the instance can be encoded
instance = URLDecoder.decode(instance, "utf-8");

View File

@ -104,6 +104,7 @@ public class Account implements Parcelable {
private List<Emojis> emojis;
private String host;
private boolean isBot;
private String social;
protected Account(Parcel in) {
id = in.readString();
@ -270,6 +271,14 @@ public class Account implements Parcelable {
this.stored_displayname = stored_displayname;
}
public String getSocial() {
return social;
}
public void setSocial(String social) {
this.social = social;
}
public enum followAction{
FOLLOW,

File diff suppressed because it is too large Load Diff

View File

@ -193,7 +193,10 @@ public class Helper {
public static final String TAG = "mastodon_etalab";
public static final String CLIENT_NAME_VALUE = "Mastalab";
public static final String OAUTH_SCOPES = "read write follow";
public static final String OAUTH_SCOPES_PEERTUBE = "user";
public static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
public static final String PREF_KEY_ID = "userID";
public static final String PREF_INSTANCE = "instance";
public static final String REDIRECT_CONTENT = "urn:ietf:wg:oauth:2.0:oob";

View File

@ -69,6 +69,7 @@ public class AccountDAO {
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()));
values.put(Sqlite.COL_SOCIAL, account.getSocial());
if( account.getToken() != null)
values.put(Sqlite.COL_OAUTHTOKEN, account.getToken());
@ -243,7 +244,7 @@ public class AccountDAO {
account.setInstance(c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)));
account.setEmojis(Helper.restoreEmojisFromString(c.getString(c.getColumnIndex(Sqlite.COL_EMOJIS))));
account.setToken(c.getString(c.getColumnIndex(Sqlite.COL_OAUTHTOKEN)));
account.setSocial(c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL))!=null?c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL)):"MASTODON");
//Close the cursor
c.close();
@ -282,6 +283,7 @@ public class AccountDAO {
account.setCreated_at(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_CREATED_AT))));
account.setInstance(c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)));
account.setToken(c.getString(c.getColumnIndex(Sqlite.COL_OAUTHTOKEN)));
account.setSocial(c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL))!=null?c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL)):"MASTODON");
accounts.add(account);
}
//Close the cursor

View File

@ -26,7 +26,7 @@ import android.database.sqlite.SQLiteOpenHelper;
public class Sqlite extends SQLiteOpenHelper {
public static final int DB_VERSION = 22;
public static final int DB_VERSION = 23;
public static final String DB_NAME = "mastodon_etalab_db";
public static SQLiteDatabase db;
private static Sqlite sInstance;
@ -82,7 +82,7 @@ public class Sqlite extends SQLiteOpenHelper {
static final String COL_INSTANCE = "INSTANCE";
static final String COL_OAUTHTOKEN = "OAUTH_TOKEN";
static final String COL_EMOJIS = "EMOJIS";
static final String COL_SOCIAL = "SOCIAL";
private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " ("
+ COL_USER_ID + " TEXT PRIMARY KEY, " + COL_USERNAME + " TEXT NOT NULL, " + COL_ACCT + " TEXT NOT NULL, "
@ -92,6 +92,7 @@ public class Sqlite extends SQLiteOpenHelper {
+ COL_AVATAR + " TEXT NOT NULL, "+ COL_AVATAR_STATIC + " TEXT NOT NULL, "
+ COL_HEADER + " TEXT NOT NULL, "+ COL_HEADER_STATIC + " TEXT NOT NULL, "
+ COL_EMOJIS + " TEXT, "
+ COL_SOCIAL + " TEXT, "
+ COL_INSTANCE + " TEXT NOT NULL, " + COL_OAUTHTOKEN + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL)";
@ -306,6 +307,8 @@ public class Sqlite extends SQLiteOpenHelper {
if( oldVersion > 6) {
db.execSQL("ALTER TABLE " + TABLE_SEARCH + " ADD COLUMN " + COL_NAME + " TEXT");
}
case 22:
db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_SOCIAL + " TEXT");
default:
break;
}

View File

@ -77,6 +77,11 @@
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
<CheckBox
android:id="@+id/peertube_instance"
android:layout_width="wrap_content"
android:text="@string/peertube_instance"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.design.widget.TextInputLayout>
<LinearLayout

View File

@ -83,7 +83,11 @@
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
<CheckBox
android:id="@+id/peertube_instance"
android:layout_width="wrap_content"
android:text="@string/peertube_instance"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"