Allow to ask admin scope during authentication

This commit is contained in:
Thomas 2022-05-26 15:27:42 +02:00
parent 7cc101cb10
commit 1f347ccf98
11 changed files with 73 additions and 60 deletions

View file

@ -651,6 +651,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
.observe(BaseMainActivity.this, filters -> mainFilters = filters); .observe(BaseMainActivity.this, filters -> mainFilters = filters);
new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getConnectedAccount(currentInstance, currentToken) new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getConnectedAccount(currentInstance, currentToken)
.observe(BaseMainActivity.this, account1 -> { .observe(BaseMainActivity.this, account1 -> {
BaseMainActivity.accountWeakReference.get().mastodon_account = account1; BaseMainActivity.accountWeakReference.get().mastodon_account = account1;
}); });
//Update pinned timelines //Update pinned timelines

View file

@ -96,7 +96,7 @@ public class LoginActivity extends BaseActivity {
if (requestedAdmin) { if (requestedAdmin) {
AdminVM adminVM = new ViewModelProvider(LoginActivity.this).get(AdminVM.class); AdminVM adminVM = new ViewModelProvider(LoginActivity.this).get(AdminVM.class);
adminVM.getAccount(account.instance, account.token, account.user_id).observe(LoginActivity.this, adminAccount -> { 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); WebviewConnectActivity.proceedLogin(LoginActivity.this, account);
}); });
} else { } else {

View file

@ -69,7 +69,7 @@ public class SettingsActivity extends BaseActivity {
binding.setTheming.setOnClickListener(v -> displaySettings(SettingsEnum.THEMING)); binding.setTheming.setOnClickListener(v -> displaySettings(SettingsEnum.THEMING));
binding.setAdministration.setOnClickListener(v -> displaySettings(SettingsEnum.ADMINISTRATION)); binding.setAdministration.setOnClickListener(v -> displaySettings(SettingsEnum.ADMINISTRATION));
binding.setLanguage.setOnClickListener(v -> displaySettings(SettingsEnum.LANGUAGE)); binding.setLanguage.setOnClickListener(v -> displaySettings(SettingsEnum.LANGUAGE));
if (MainActivity.accountWeakReference.get().mastodon_account.admin) { if (MainActivity.accountWeakReference.get().admin) {
binding.setAdministration.setVisibility(View.VISIBLE); binding.setAdministration.setVisibility(View.VISIBLE);
} else { } else {
binding.setAdministration.setVisibility(View.GONE); binding.setAdministration.setVisibility(View.GONE);

View file

@ -31,7 +31,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;
@ -95,7 +94,6 @@ public class WebviewConnectActivity extends BaseActivity {
new Thread(() -> { new Thread(() -> {
try { try {
//update the database //update the database
Log.v(Helper.TAG, "account.mastodon_account.admin: " + account.mastodon_account.admin);
new Account(activity).insertOrUpdate(account); new Account(activity).insertOrUpdate(account);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
BaseMainActivity.currentToken = account.token; BaseMainActivity.currentToken = account.token;
@ -134,7 +132,6 @@ public class WebviewConnectActivity extends BaseActivity {
requestedAdmin = b.getBoolean("requestedAdmin", false); requestedAdmin = b.getBoolean("requestedAdmin", false);
} }
Log.v(Helper.TAG, "requestedAdmin: " + requestedAdmin);
if (login_url == null) if (login_url == null)
finish(); finish();
ActionBar actionBar = getSupportActionBar(); ActionBar actionBar = getSupportActionBar();
@ -243,12 +240,8 @@ public class WebviewConnectActivity extends BaseActivity {
//We check if user have really moderator rights //We check if user have really moderator rights
if (requestedAdmin) { if (requestedAdmin) {
AdminVM adminVM = new ViewModelProvider(WebviewConnectActivity.this).get(AdminVM.class); 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 -> { adminVM.getAccount(account.instance, account.token, account.user_id).observe(WebviewConnectActivity.this, adminAccount -> {
Log.v(Helper.TAG, "adminAccount: " + adminAccount); account.admin = adminAccount != null;
account.mastodon_account.admin = adminAccount != null;
proceedLogin(WebviewConnectActivity.this, account); proceedLogin(WebviewConnectActivity.this, account);
}); });
} else { } else {

View file

@ -30,34 +30,34 @@ import retrofit2.http.Query;
public interface MastodonAdminService { public interface MastodonAdminService {
@GET("/admin/accounts") @GET("admin/accounts")
Call<List<AdminAccount>> getAccounts( Call<List<AdminAccount>> getAccounts(
@Header("Authorization") String token, @Header("Authorization") String token,
@Query("local") boolean local, @Query("local") Boolean local,
@Query("remote") boolean remote, @Query("remote") Boolean remote,
@Query("by_domain") String by_domain, @Query("by_domain") String by_domain,
@Query("active") boolean active, @Query("active") Boolean active,
@Query("pending") boolean pending, @Query("pending") Boolean pending,
@Query("disabled") boolean disabled, @Query("disabled") Boolean disabled,
@Query("silenced") boolean silenced, @Query("silenced") Boolean silenced,
@Query("suspended") boolean suspended, @Query("suspended") Boolean suspended,
@Query("username") String username, @Query("username") String username,
@Query("display_name") String display_name, @Query("display_name") String display_name,
@Query("email") String email, @Query("email") String email,
@Query("ip") String ip, @Query("ip") String ip,
@Query("staff") boolean staff, @Query("staff") Boolean staff,
@Query("max_id") String max_id, @Query("max_id") String max_id,
@Query("since_id") String since_id, @Query("since_id") String since_id,
@Query("limit") int limit @Query("limit") Integer limit
); );
@GET("/admin/accounts/{id}") @GET("admin/accounts/{id}")
Call<AdminAccount> getAccount( Call<AdminAccount> getAccount(
@Header("Authorization") String token, @Header("Authorization") String token,
@Path("id") String id @Path("id") String id
); );
@POST("/admin/accounts/{account_id}/action") @POST("admin/accounts/{account_id}/action")
Call<Void> performAction( Call<Void> performAction(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("account_id") String account_id, @Path("account_id") String account_id,
@ -65,83 +65,83 @@ public interface MastodonAdminService {
@Field("report_id") String report_id, @Field("report_id") String report_id,
@Field("warning_preset_id") String warning_preset_id, @Field("warning_preset_id") String warning_preset_id,
@Field("text") String text, @Field("text") String text,
@Field("send_email_notification") boolean send_email_notification @Field("send_email_notification") Boolean send_email_notification
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/accounts/{account_id}/approve") @POST("admin/accounts/{account_id}/approve")
Call<AdminAccount> approve( Call<AdminAccount> approve(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("account_id") String account_id @Path("account_id") String account_id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/accounts/{account_id}/reject") @POST("admin/accounts/{account_id}/reject")
Call<AdminAccount> reject( Call<AdminAccount> reject(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("account_id") String account_id @Path("account_id") String account_id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/accounts/{account_id}/enable") @POST("admin/accounts/{account_id}/enable")
Call<AdminAccount> enable( Call<AdminAccount> enable(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("account_id") String account_id @Path("account_id") String account_id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/accounts/{account_id}/unsilence") @POST("admin/accounts/{account_id}/unsilence")
Call<AdminAccount> unsilence( Call<AdminAccount> unsilence(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("account_id") String account_id @Path("account_id") String account_id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/accounts/{account_id}/unsuspend") @POST("admin/accounts/{account_id}/unsuspend")
Call<AdminAccount> unsuspend( Call<AdminAccount> unsuspend(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("account_id") String account_id @Path("account_id") String account_id
); );
@FormUrlEncoded @FormUrlEncoded
@GET("/admin/reports") @GET("admin/reports")
Call<List<AdminReport>> getReports( Call<List<AdminReport>> getReports(
@Header("Authorization") String token, @Header("Authorization") String token,
@Field("resolved") boolean resolved, @Field("resolved") Boolean resolved,
@Field("account_id") String account_id, @Field("account_id") String account_id,
@Field("target_account_id") String target_account_id @Field("target_account_id") String target_account_id
); );
@FormUrlEncoded @FormUrlEncoded
@GET("/admin/reports/{id}") @GET("admin/reports/{id}")
Call<AdminReport> getReport( Call<AdminReport> getReport(
@Header("Authorization") String token, @Header("Authorization") String token,
@Path("id") String id @Path("id") String id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/reports/{id}/assign_to_self") @POST("admin/reports/{id}/assign_to_self")
Call<AdminReport> assignToSelf( Call<AdminReport> assignToSelf(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("id") String id @Path("id") String id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/reports/{id}/unassign") @POST("admin/reports/{id}/unassign")
Call<AdminReport> unassign( Call<AdminReport> unassign(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("id") String id @Path("id") String id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/reports/{id}/resolve") @POST("admin/reports/{id}/resolve")
Call<AdminReport> resolved( Call<AdminReport> resolved(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("id") String id @Path("id") String id
); );
@FormUrlEncoded @FormUrlEncoded
@POST("/admin/reports/{id}/reopen") @POST("admin/reports/{id}/reopen")
Call<AdminReport> reopen( Call<AdminReport> reopen(
@Header("Authorization") String app_token, @Header("Authorization") String app_token,
@Path("id") String id @Path("id") String id

View file

@ -73,9 +73,6 @@ public class Account implements Serializable {
public Date mute_expires_at; public Date mute_expires_at;
@SerializedName("moved") @SerializedName("moved")
public Account moved; public Account moved;
//Local var
@SerializedName("admin")
public boolean admin;
//Some extra spannable element - They will be filled automatically when fetching the account //Some extra spannable element - They will be filled automatically when fetching the account
public transient Spannable span_display_name; public transient Spannable span_display_name;

View file

@ -17,6 +17,7 @@ package app.fedilab.android.client.entities.api;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.Date; import java.util.Date;
import java.util.List;
public class AdminAccount { public class AdminAccount {
@ -31,7 +32,9 @@ public class AdminAccount {
@SerializedName("email") @SerializedName("email")
public String email; public String email;
@SerializedName("ip") @SerializedName("ip")
public String ip; public IP ip;
@SerializedName("ips")
public List<IP> ips;
@SerializedName("locale") @SerializedName("locale")
public String locale; public String locale;
@SerializedName("invite_request") @SerializedName("invite_request")
@ -54,4 +57,14 @@ public class AdminAccount {
public String created_by_application_id; public String created_by_application_id;
@SerializedName("invited_by_account_id") @SerializedName("invited_by_account_id")
public String 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;
}
} }

View file

@ -65,6 +65,8 @@ public class Account implements Serializable {
public Date updated_at; public Date updated_at;
@SerializedName("mastodon_account") @SerializedName("mastodon_account")
public app.fedilab.android.client.entities.api.Account mastodon_account; public app.fedilab.android.client.entities.api.Account mastodon_account;
@SerializedName("admin")
public boolean admin;
private transient Context context; 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_VALIDITY, account.token_validity);
values.put(Sqlite.COL_TOKEN, account.token); values.put(Sqlite.COL_TOKEN, account.token);
values.put(Sqlite.COL_REFRESH_TOKEN, account.refresh_token); values.put(Sqlite.COL_REFRESH_TOKEN, account.refresh_token);
values.put(Sqlite.COL_ADMIN, account.admin);
if (account.mastodon_account != null) { if (account.mastodon_account != null) {
values.put(Sqlite.COL_ACCOUNT, mastodonAccountToStringStorage(account.mastodon_account)); 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_VALIDITY, account.token_validity);
values.put(Sqlite.COL_TOKEN, account.token); values.put(Sqlite.COL_TOKEN, account.token);
values.put(Sqlite.COL_REFRESH_TOKEN, account.refresh_token); values.put(Sqlite.COL_REFRESH_TOKEN, account.refresh_token);
values.put(Sqlite.COL_ADMIN, account.admin);
} }
if (account.mastodon_account != null) { if (account.mastodon_account != null) {
values.put(Sqlite.COL_ACCOUNT, mastodonAccountToStringStorage(account.mastodon_account)); 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.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.updated_at = Helper.stringToDate(context, c.getString(c.getColumnIndexOrThrow(Sqlite.COL_UPDATED_AT)));
account.software = c.getString(c.getColumnIndexOrThrow(Sqlite.COL_SOFTWARE)); 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)); String apiStr = c.getString(c.getColumnIndexOrThrow(Sqlite.COL_API));
API api; API api;
switch (apiStr) { switch (apiStr) {

View file

@ -23,7 +23,7 @@ import android.database.sqlite.SQLiteOpenHelper;
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 = "fedilab_db"; public static final String DB_NAME = "fedilab_db";
//Table of owned accounts //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_APP_CLIENT_ID = "APP_CLIENT_ID";
public static final String COL_CREATED_AT = "CREATED_AT"; public static final String COL_CREATED_AT = "CREATED_AT";
public static final String COL_UPDATED_AT = "UPDATED_AT"; public static final String COL_UPDATED_AT = "UPDATED_AT";
public static final String COL_ADMIN = "ADMIN";
//Table for timelines //Table for timelines
public static final String TABLE_TIMELINES = "TIMELINES"; public static final String TABLE_TIMELINES = "TIMELINES";
public static final String COL_ID = "ID"; 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_ID + " TEXT NOT NULL, "
+ COL_APP_CLIENT_SECRET + " TEXT NOT NULL, " + COL_APP_CLIENT_SECRET + " TEXT NOT NULL, "
+ COL_CREATED_AT + " TEXT NOT NULL," + COL_CREATED_AT + " TEXT NOT NULL,"
+ COL_ADMIN + "INTEGER NOT NULL DEFAULT 0,"
+ COL_UPDATED_AT + " TEXT)"; + COL_UPDATED_AT + " TEXT)";
private static final String CREATE_TABLE_TIMELINES = "CREATE TABLE IF NOT EXISTS " + TABLE_TIMELINES + " (" private static final String CREATE_TABLE_TIMELINES = "CREATE TABLE IF NOT EXISTS " + TABLE_TIMELINES + " ("
+ COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
@ -210,6 +212,8 @@ public class Sqlite extends SQLiteOpenHelper {
db.execSQL(CREATE_TABLE_QUICK_LOAD); db.execSQL(CREATE_TABLE_QUICK_LOAD);
case 2: case 2:
db.execSQL(CREATE_TABLE_BOTTOM_MENU); 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: default:
break; break;
} }

View file

@ -252,7 +252,7 @@ public class FragmentMastodonContext extends Fragment {
binding.recyclerView.removeItemDecorationAt(i); binding.recyclerView.removeItemDecorationAt(i);
} }
} }
List<LineInfo> threadDecorationInfo = getThreadDecorationInfo(context, focusedStatus.id); List<LineInfo> threadDecorationInfo = getThreadDecorationInfo(context);
recyclerViewThreadLines = new RecyclerViewThreadLines(requireContext(), threadDecorationInfo); recyclerViewThreadLines = new RecyclerViewThreadLines(requireContext(), threadDecorationInfo);
binding.recyclerView.addItemDecoration(recyclerViewThreadLines); binding.recyclerView.addItemDecoration(recyclerViewThreadLines);
binding.swipeContainer.setRefreshing(false); binding.swipeContainer.setRefreshing(false);

View file

@ -83,24 +83,24 @@ public class AdminVM extends AndroidViewModel {
* @param staff Filter for staff accounts? * @param staff Filter for staff accounts?
* @return {@link LiveData} containing a {@link List} of {@link AdminAccount}s * @return {@link LiveData} containing a {@link List} of {@link AdminAccount}s
*/ */
private LiveData<List<AdminAccount>> getAccounts(@NonNull String instance, public LiveData<List<AdminAccount>> getAccounts(@NonNull String instance,
String token, String token,
boolean local, Boolean local,
boolean remote, Boolean remote,
String byDomain, String byDomain,
boolean active, Boolean active,
boolean pending, Boolean pending,
boolean disabled, Boolean disabled,
boolean silenced, Boolean silenced,
boolean suspended, Boolean suspended,
String username, String username,
String displayName, String displayName,
String email, String email,
String ip, String ip,
boolean staff, Boolean staff,
String maxId, String maxId,
String sinceId, String sinceId,
int limit) { Integer limit) {
MastodonAdminService mastodonAdminService = init(instance); MastodonAdminService mastodonAdminService = init(instance);
adminAccountListMutableLiveData = new MutableLiveData<>(); adminAccountListMutableLiveData = new MutableLiveData<>();
new Thread(() -> { new Thread(() -> {
@ -360,7 +360,7 @@ public class AdminVM extends AndroidViewModel {
*/ */
public LiveData<List<AdminReport>> getReports(@NonNull String instance, public LiveData<List<AdminReport>> getReports(@NonNull String instance,
String token, String token,
boolean resolved, Boolean resolved,
String accountId, String accountId,
String targetAccountId) { String targetAccountId) {
MastodonAdminService mastodonAdminService = init(instance); MastodonAdminService mastodonAdminService = init(instance);