From 1f347ccf981675c2e108c5a3b9bf5cc85c7f108f Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 26 May 2022 15:27:42 +0200 Subject: [PATCH] Allow to ask admin scope during authentication --- .../app/fedilab/android/BaseMainActivity.java | 1 + .../android/activities/LoginActivity.java | 2 +- .../android/activities/SettingsActivity.java | 2 +- .../activities/WebviewConnectActivity.java | 9 +--- .../endpoints/MastodonAdminService.java | 50 +++++++++---------- .../android/client/entities/api/Account.java | 3 -- .../client/entities/api/AdminAccount.java | 15 +++++- .../android/client/entities/app/Account.java | 5 ++ .../app/fedilab/android/sqlite/Sqlite.java | 6 ++- .../timeline/FragmentMastodonContext.java | 2 +- .../android/viewmodel/mastodon/AdminVM.java | 38 +++++++------- 11 files changed, 73 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index e1ec26b50..a6c5f31d6 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -651,6 +651,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt .observe(BaseMainActivity.this, filters -> mainFilters = filters); new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getConnectedAccount(currentInstance, currentToken) .observe(BaseMainActivity.this, account1 -> { + BaseMainActivity.accountWeakReference.get().mastodon_account = account1; }); //Update pinned timelines diff --git a/app/src/main/java/app/fedilab/android/activities/LoginActivity.java b/app/src/main/java/app/fedilab/android/activities/LoginActivity.java index e790cf491..2f2991a38 100644 --- a/app/src/main/java/app/fedilab/android/activities/LoginActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/LoginActivity.java @@ -96,7 +96,7 @@ public class LoginActivity extends BaseActivity { if (requestedAdmin) { AdminVM adminVM = new ViewModelProvider(LoginActivity.this).get(AdminVM.class); adminVM.getAccount(account.instance, account.token, account.user_id).observe(LoginActivity.this, adminAccount -> { - account.mastodon_account.admin = adminAccount != null; + account.admin = adminAccount != null; WebviewConnectActivity.proceedLogin(LoginActivity.this, account); }); } else { diff --git a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java index fdb46aca3..8946d0a23 100644 --- a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.java @@ -69,7 +69,7 @@ public class SettingsActivity extends BaseActivity { binding.setTheming.setOnClickListener(v -> displaySettings(SettingsEnum.THEMING)); binding.setAdministration.setOnClickListener(v -> displaySettings(SettingsEnum.ADMINISTRATION)); binding.setLanguage.setOnClickListener(v -> displaySettings(SettingsEnum.LANGUAGE)); - if (MainActivity.accountWeakReference.get().mastodon_account.admin) { + if (MainActivity.accountWeakReference.get().admin) { binding.setAdministration.setVisibility(View.VISIBLE); } else { binding.setAdministration.setVisibility(View.GONE); diff --git a/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java b/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java index 590d74ca8..bdc8bb01b 100644 --- a/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java @@ -31,7 +31,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; @@ -95,7 +94,6 @@ public class WebviewConnectActivity extends BaseActivity { new Thread(() -> { try { //update the database - Log.v(Helper.TAG, "account.mastodon_account.admin: " + account.mastodon_account.admin); new Account(activity).insertOrUpdate(account); Handler mainHandler = new Handler(Looper.getMainLooper()); BaseMainActivity.currentToken = account.token; @@ -134,7 +132,6 @@ public class WebviewConnectActivity extends BaseActivity { requestedAdmin = b.getBoolean("requestedAdmin", false); } - Log.v(Helper.TAG, "requestedAdmin: " + requestedAdmin); if (login_url == null) finish(); ActionBar actionBar = getSupportActionBar(); @@ -243,12 +240,8 @@ public class WebviewConnectActivity extends BaseActivity { //We check if user have really moderator rights if (requestedAdmin) { AdminVM adminVM = new ViewModelProvider(WebviewConnectActivity.this).get(AdminVM.class); - Log.v(Helper.TAG, " account.instance: " + account.instance); - Log.v(Helper.TAG, " account.token: " + account.token); - Log.v(Helper.TAG, " account.user_id: " + account.user_id); adminVM.getAccount(account.instance, account.token, account.user_id).observe(WebviewConnectActivity.this, adminAccount -> { - Log.v(Helper.TAG, "adminAccount: " + adminAccount); - account.mastodon_account.admin = adminAccount != null; + account.admin = adminAccount != null; proceedLogin(WebviewConnectActivity.this, account); }); } else { diff --git a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAdminService.java b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAdminService.java index 5cde16f65..11a3efc26 100644 --- a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAdminService.java +++ b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAdminService.java @@ -30,34 +30,34 @@ import retrofit2.http.Query; public interface MastodonAdminService { - @GET("/admin/accounts") + @GET("admin/accounts") Call> getAccounts( @Header("Authorization") String token, - @Query("local") boolean local, - @Query("remote") boolean remote, + @Query("local") Boolean local, + @Query("remote") Boolean remote, @Query("by_domain") String by_domain, - @Query("active") boolean active, - @Query("pending") boolean pending, - @Query("disabled") boolean disabled, - @Query("silenced") boolean silenced, - @Query("suspended") boolean suspended, + @Query("active") Boolean active, + @Query("pending") Boolean pending, + @Query("disabled") Boolean disabled, + @Query("silenced") Boolean silenced, + @Query("suspended") Boolean suspended, @Query("username") String username, @Query("display_name") String display_name, @Query("email") String email, @Query("ip") String ip, - @Query("staff") boolean staff, + @Query("staff") Boolean staff, @Query("max_id") String max_id, @Query("since_id") String since_id, - @Query("limit") int limit + @Query("limit") Integer limit ); - @GET("/admin/accounts/{id}") + @GET("admin/accounts/{id}") Call getAccount( @Header("Authorization") String token, @Path("id") String id ); - @POST("/admin/accounts/{account_id}/action") + @POST("admin/accounts/{account_id}/action") Call performAction( @Header("Authorization") String app_token, @Path("account_id") String account_id, @@ -65,83 +65,83 @@ public interface MastodonAdminService { @Field("report_id") String report_id, @Field("warning_preset_id") String warning_preset_id, @Field("text") String text, - @Field("send_email_notification") boolean send_email_notification + @Field("send_email_notification") Boolean send_email_notification ); @FormUrlEncoded - @POST("/admin/accounts/{account_id}/approve") + @POST("admin/accounts/{account_id}/approve") Call approve( @Header("Authorization") String app_token, @Path("account_id") String account_id ); @FormUrlEncoded - @POST("/admin/accounts/{account_id}/reject") + @POST("admin/accounts/{account_id}/reject") Call reject( @Header("Authorization") String app_token, @Path("account_id") String account_id ); @FormUrlEncoded - @POST("/admin/accounts/{account_id}/enable") + @POST("admin/accounts/{account_id}/enable") Call enable( @Header("Authorization") String app_token, @Path("account_id") String account_id ); @FormUrlEncoded - @POST("/admin/accounts/{account_id}/unsilence") + @POST("admin/accounts/{account_id}/unsilence") Call unsilence( @Header("Authorization") String app_token, @Path("account_id") String account_id ); @FormUrlEncoded - @POST("/admin/accounts/{account_id}/unsuspend") + @POST("admin/accounts/{account_id}/unsuspend") Call unsuspend( @Header("Authorization") String app_token, @Path("account_id") String account_id ); @FormUrlEncoded - @GET("/admin/reports") + @GET("admin/reports") Call> getReports( @Header("Authorization") String token, - @Field("resolved") boolean resolved, + @Field("resolved") Boolean resolved, @Field("account_id") String account_id, @Field("target_account_id") String target_account_id ); @FormUrlEncoded - @GET("/admin/reports/{id}") + @GET("admin/reports/{id}") Call getReport( @Header("Authorization") String token, @Path("id") String id ); @FormUrlEncoded - @POST("/admin/reports/{id}/assign_to_self") + @POST("admin/reports/{id}/assign_to_self") Call assignToSelf( @Header("Authorization") String app_token, @Path("id") String id ); @FormUrlEncoded - @POST("/admin/reports/{id}/unassign") + @POST("admin/reports/{id}/unassign") Call unassign( @Header("Authorization") String app_token, @Path("id") String id ); @FormUrlEncoded - @POST("/admin/reports/{id}/resolve") + @POST("admin/reports/{id}/resolve") Call resolved( @Header("Authorization") String app_token, @Path("id") String id ); @FormUrlEncoded - @POST("/admin/reports/{id}/reopen") + @POST("admin/reports/{id}/reopen") Call reopen( @Header("Authorization") String app_token, @Path("id") String id diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Account.java b/app/src/main/java/app/fedilab/android/client/entities/api/Account.java index fb389ce4d..1905ad42f 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Account.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Account.java @@ -73,9 +73,6 @@ public class Account implements Serializable { public Date mute_expires_at; @SerializedName("moved") public Account moved; - //Local var - @SerializedName("admin") - public boolean admin; //Some extra spannable element - They will be filled automatically when fetching the account public transient Spannable span_display_name; diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/AdminAccount.java b/app/src/main/java/app/fedilab/android/client/entities/api/AdminAccount.java index 2cfe93e35..8faf845d7 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/AdminAccount.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/AdminAccount.java @@ -17,6 +17,7 @@ package app.fedilab.android.client.entities.api; import com.google.gson.annotations.SerializedName; import java.util.Date; +import java.util.List; public class AdminAccount { @@ -31,7 +32,9 @@ public class AdminAccount { @SerializedName("email") public String email; @SerializedName("ip") - public String ip; + public IP ip; + @SerializedName("ips") + public List ips; @SerializedName("locale") public String locale; @SerializedName("invite_request") @@ -54,4 +57,14 @@ public class AdminAccount { public String created_by_application_id; @SerializedName("invited_by_account_id") public String invited_by_account_id; + + + public final class IP { + @SerializedName("ip") + public String ip; + @SerializedName("used_at") + public Date used_at; + @SerializedName("user_id") + public String user_id; + } } diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/Account.java b/app/src/main/java/app/fedilab/android/client/entities/app/Account.java index b0b710104..ca6f1e68f 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/Account.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/Account.java @@ -65,6 +65,8 @@ public class Account implements Serializable { public Date updated_at; @SerializedName("mastodon_account") public app.fedilab.android.client.entities.api.Account mastodon_account; + @SerializedName("admin") + public boolean admin; private transient Context context; @@ -165,6 +167,7 @@ public class Account implements Serializable { values.put(Sqlite.COL_TOKEN_VALIDITY, account.token_validity); values.put(Sqlite.COL_TOKEN, account.token); values.put(Sqlite.COL_REFRESH_TOKEN, account.refresh_token); + values.put(Sqlite.COL_ADMIN, account.admin); if (account.mastodon_account != null) { values.put(Sqlite.COL_ACCOUNT, mastodonAccountToStringStorage(account.mastodon_account)); } @@ -200,6 +203,7 @@ public class Account implements Serializable { values.put(Sqlite.COL_TOKEN_VALIDITY, account.token_validity); values.put(Sqlite.COL_TOKEN, account.token); values.put(Sqlite.COL_REFRESH_TOKEN, account.refresh_token); + values.put(Sqlite.COL_ADMIN, account.admin); } if (account.mastodon_account != null) { values.put(Sqlite.COL_ACCOUNT, mastodonAccountToStringStorage(account.mastodon_account)); @@ -430,6 +434,7 @@ public class Account implements Serializable { account.created_at = Helper.stringToDate(context, c.getString(c.getColumnIndexOrThrow(Sqlite.COL_CREATED_AT))); account.updated_at = Helper.stringToDate(context, c.getString(c.getColumnIndexOrThrow(Sqlite.COL_UPDATED_AT))); account.software = c.getString(c.getColumnIndexOrThrow(Sqlite.COL_SOFTWARE)); + account.admin = c.getInt(c.getColumnIndexOrThrow(Sqlite.COL_ADMIN)) == 1; String apiStr = c.getString(c.getColumnIndexOrThrow(Sqlite.COL_API)); API api; switch (apiStr) { diff --git a/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java b/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java index 5f650e686..895184dcd 100644 --- a/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java +++ b/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java @@ -23,7 +23,7 @@ import android.database.sqlite.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 = "fedilab_db"; //Table of owned accounts @@ -42,6 +42,7 @@ public class Sqlite extends SQLiteOpenHelper { public static final String COL_APP_CLIENT_ID = "APP_CLIENT_ID"; public static final String COL_CREATED_AT = "CREATED_AT"; public static final String COL_UPDATED_AT = "UPDATED_AT"; + public static final String COL_ADMIN = "ADMIN"; //Table for timelines public static final String TABLE_TIMELINES = "TIMELINES"; public static final String COL_ID = "ID"; @@ -94,6 +95,7 @@ public class Sqlite extends SQLiteOpenHelper { + COL_APP_CLIENT_ID + " TEXT NOT NULL, " + COL_APP_CLIENT_SECRET + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL," + + COL_ADMIN + "INTEGER NOT NULL DEFAULT 0," + COL_UPDATED_AT + " TEXT)"; private static final String CREATE_TABLE_TIMELINES = "CREATE TABLE IF NOT EXISTS " + TABLE_TIMELINES + " (" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " @@ -210,6 +212,8 @@ public class Sqlite extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_QUICK_LOAD); case 2: db.execSQL(CREATE_TABLE_BOTTOM_MENU); + case 3: + db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_ADMIN + " INTEGER NOT NULL DEFAULT 0"); default: break; } diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java index f7a83cddb..03e8c033e 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java @@ -252,7 +252,7 @@ public class FragmentMastodonContext extends Fragment { binding.recyclerView.removeItemDecorationAt(i); } } - List threadDecorationInfo = getThreadDecorationInfo(context, focusedStatus.id); + List threadDecorationInfo = getThreadDecorationInfo(context); recyclerViewThreadLines = new RecyclerViewThreadLines(requireContext(), threadDecorationInfo); binding.recyclerView.addItemDecoration(recyclerViewThreadLines); binding.swipeContainer.setRefreshing(false); diff --git a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AdminVM.java b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AdminVM.java index 33d4dfcf9..ba145b856 100644 --- a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AdminVM.java +++ b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AdminVM.java @@ -83,24 +83,24 @@ public class AdminVM extends AndroidViewModel { * @param staff Filter for staff accounts? * @return {@link LiveData} containing a {@link List} of {@link AdminAccount}s */ - private LiveData> getAccounts(@NonNull String instance, - String token, - boolean local, - boolean remote, - String byDomain, - boolean active, - boolean pending, - boolean disabled, - boolean silenced, - boolean suspended, - String username, - String displayName, - String email, - String ip, - boolean staff, - String maxId, - String sinceId, - int limit) { + public LiveData> getAccounts(@NonNull String instance, + String token, + Boolean local, + Boolean remote, + String byDomain, + Boolean active, + Boolean pending, + Boolean disabled, + Boolean silenced, + Boolean suspended, + String username, + String displayName, + String email, + String ip, + Boolean staff, + String maxId, + String sinceId, + Integer limit) { MastodonAdminService mastodonAdminService = init(instance); adminAccountListMutableLiveData = new MutableLiveData<>(); new Thread(() -> { @@ -360,7 +360,7 @@ public class AdminVM extends AndroidViewModel { */ public LiveData> getReports(@NonNull String instance, String token, - boolean resolved, + Boolean resolved, String accountId, String targetAccountId) { MastodonAdminService mastodonAdminService = init(instance);