From d14ecd9c6893398a8f9a3edd325fdd9ab4179ca7 Mon Sep 17 00:00:00 2001 From: 6543 <6543@noreply@gitea.io> Date: Tue, 22 Oct 2019 15:27:33 +0000 Subject: [PATCH] Version Check before try to Login (#147) --- .../mian/gitnex/activities/LoginActivity.java | 104 ++++++++++++-- .../mian/gitnex/fragments/AboutFragment.java | 83 +---------- .../org/mian/gitnex/helpers/VersionCheck.java | 135 ++++++++++++++++++ .../mian/gitnex/interfaces/ApiInterface.java | 2 +- app/src/main/res/layout/fragment_about.xml | 17 --- app/src/main/res/values/strings.xml | 13 ++ 6 files changed, 247 insertions(+), 107 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/helpers/VersionCheck.java diff --git a/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java b/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java index 2ccd58be..5bf03058 100644 --- a/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java @@ -1,9 +1,9 @@ package org.mian.gitnex.activities; import android.annotation.SuppressLint; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; import android.content.res.Resources; import android.graphics.drawable.GradientDrawable; import android.os.Bundle; @@ -17,19 +17,23 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; import com.tooltip.Tooltip; +import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.helpers.VersionCheck; +import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.UserTokens; import org.mian.gitnex.util.AppUtil; -import org.mian.gitnex.R; import org.mian.gitnex.util.TinyDB; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.Objects; import okhttp3.Credentials; -import okhttp3.Headers; import retrofit2.Call; import retrofit2.Callback; @@ -42,6 +46,7 @@ public class LoginActivity extends AppCompatActivity implements View.OnClickList private Button login_button; private EditText instance_url, login_uid, login_passwd, otpCode; private Spinner protocolSpinner; + final Context ctx = this; @Override protected void onCreate(Bundle savedInstanceState) { @@ -58,10 +63,10 @@ public class LoginActivity extends AppCompatActivity implements View.OnClickList login_passwd = findViewById(R.id.login_passwd); otpCode = findViewById(R.id.otpCode); ImageView info_button = findViewById(R.id.info); - final TextView viewTextGiteaVersion = findViewById(R.id.appVersion); + final TextView viewTextAppVersion = findViewById(R.id.appVersion); protocolSpinner = findViewById(R.id.httpsSpinner); - viewTextGiteaVersion.setText(AppUtil.getAppVersion(getApplicationContext())); + viewTextAppVersion.setText(AppUtil.getAppVersion(getApplicationContext())); Resources res = getResources(); String[] allProtocols = res.getStringArray(R.array.protocolValues); @@ -254,7 +259,7 @@ public class LoginActivity extends AppCompatActivity implements View.OnClickList } - letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP); + versionCheck(instanceUrl, loginUid, loginPass, loginOTP); } else { @@ -265,6 +270,87 @@ public class LoginActivity extends AppCompatActivity implements View.OnClickList } + private void versionCheck(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP) { + + final TinyDB tinyDb = new TinyDB(getApplicationContext()); + + Call callVersion = RetrofitClient + .getInstance(instanceUrl) + .getApiInterface() + .getGiteaVersion(); + + callVersion.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull final Call callVersion, @NonNull retrofit2.Response responseVersion) { + + if (responseVersion.code() == 200) { + + GiteaVersion version = responseVersion.body(); + assert version != null; + + VersionCheck vt = VersionCheck.check(getString(R.string.versionLow), getString(R.string.versionHigh), version.getVersion()); + tinyDb.putString("giteaVersion", version.getVersion()); + + switch (vt) { + case UNSUPPORTED_NEW: + //Toasty.info(getApplicationContext(), getString(R.string.versionUnsupportedNew)); + case SUPPORTED_LATEST: + case SUPPORTED_OLD: + case DEVELOPMENT: + letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP); + return; + case UNSUPPORTED_OLD: + + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog); + + alertDialogBuilder + .setTitle(getString(R.string.versionAlertDialogHeader)) + .setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())) + .setCancelable(true) + .setIcon(R.drawable.ic_warning) + .setNegativeButton(getString(R.string.versionAlertDialogCopyNegative), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + enableProcessButton(); + } + }) + .setPositiveButton(getString(R.string.versionAlertDialogCopyPositive), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + dialog.dismiss(); + letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP); + + } + }); + + AlertDialog alertDialog = alertDialogBuilder.create(); + + alertDialog.show(); + return; + default: // UNKNOWN + Toasty.info(getApplicationContext(), getString(R.string.versionUnknow)); + enableProcessButton(); + + } + + } + + } + + @Override + public void onFailure(@NonNull Call callVersion, Throwable t) { + + Log.e("onFailure-version", t.toString()); + + } + + }); + + } + private void letTheUserIn(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP) { final String credential = Credentials.basic(loginUid, loginPass); @@ -290,7 +376,7 @@ public class LoginActivity extends AppCompatActivity implements View.OnClickList List userTokens = response.body(); final TinyDB tinyDb = new TinyDB(getApplicationContext()); - Headers responseHeaders = response.headers(); + //Headers responseHeaders = response.headers(); if (response.isSuccessful()) { @@ -332,7 +418,7 @@ public class LoginActivity extends AppCompatActivity implements View.OnClickList @Override public void onResponse(@NonNull Call callCreateToken, @NonNull retrofit2.Response responseCreate) { - if (responseCreate.isSuccessful()) { + if(responseCreate.isSuccessful()) { if(responseCreate.code() == 201) { diff --git a/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java b/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java index e7786571..408b983b 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java @@ -6,27 +6,17 @@ import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.ProgressBar; import android.widget.TextView; import org.mian.gitnex.R; import org.mian.gitnex.activities.CreditsActivity; import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.activities.SponsorsActivity; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.TinyDB; import java.util.Objects; -import retrofit2.Response; -import retrofit2.Call; -import retrofit2.Callback; /** * Author M M Arif @@ -34,17 +24,12 @@ import retrofit2.Callback; public class AboutFragment extends Fragment { - private TextView viewTextGiteaVersion; - private ProgressBar mProgressBar; - private LinearLayout pageContent; - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_about, container, false); ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleAbout)); TinyDB tinyDb = new TinyDB(getContext()); - String instanceUrl = tinyDb.getString("instanceUrl"); final TextView appVerBuild; final TextView donationLink; @@ -55,13 +40,8 @@ public class AboutFragment extends Fragment { final TextView appWebsite; final TextView appRepo; - pageContent = v.findViewById(R.id.aboutFrame); - pageContent.setVisibility(View.GONE); - - mProgressBar = v.findViewById(R.id.progress_bar); - appVerBuild = v.findViewById(R.id.appVerBuild); - viewTextGiteaVersion = v.findViewById(R.id.giteaVersion); + TextView viewTextGiteaVersion = v.findViewById(R.id.giteaVersion); creditsButton = v.findViewById(R.id.creditsButton); donationLink = v.findViewById(R.id.donationLink); donationLinkPatreon = v.findViewById(R.id.donationLinkPatreon); @@ -134,67 +114,10 @@ public class AboutFragment extends Fragment { } }); - boolean connToInternet = AppUtil.haveNetworkConnection(getContext()); - - if(!connToInternet) { - - mProgressBar.setVisibility(View.GONE); - pageContent.setVisibility(View.VISIBLE); - - } else { - - giteaVer(instanceUrl); - - } + String commit = getResources().getString(R.string.commitPage) + tinyDb.getString("giteaVersion"); + viewTextGiteaVersion.setText(commit); return v; } - private void giteaVer(String instanceUrl) { - - TinyDB tinyDb = new TinyDB(getContext()); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - - Call call = RetrofitClient - .getInstance(instanceUrl) - .getApiInterface() - .getGiteaVersion(Authorization.returnAuthentication(getContext(), loginUid, instanceToken)); - - call.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - - if (response.isSuccessful()) { - if (response.code() == 200) { - - GiteaVersion version = response.body(); - assert version != null; - String commit = getResources().getString(R.string.commitPage) + version.getVersion(); - viewTextGiteaVersion.setText(commit); - mProgressBar.setVisibility(View.GONE); - pageContent.setVisibility(View.VISIBLE); - - } - - } - else { - - String commit = getResources().getString(R.string.commitPage); - viewTextGiteaVersion.setText(commit); - mProgressBar.setVisibility(View.GONE); - pageContent.setVisibility(View.VISIBLE); - - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - - } - } diff --git a/app/src/main/java/org/mian/gitnex/helpers/VersionCheck.java b/app/src/main/java/org/mian/gitnex/helpers/VersionCheck.java new file mode 100644 index 00000000..12a25232 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/VersionCheck.java @@ -0,0 +1,135 @@ +package org.mian.gitnex.helpers; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Author 6543 + */ + +public enum VersionCheck { + + UNKNOWN, + SUPPORTED_LATEST, + SUPPORTED_OLD, + DEVELOPMENT, + UNSUPPORTED_OLD, + UNSUPPORTED_NEW; + + public static VersionCheck check(String min, String last, String value) { + + final Pattern pattern_stable_release = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)$"); + final Pattern pattern_dev_release = Pattern.compile("^(\\d).(\\d+).(\\d+)(\\D)(.+)"); + Matcher match; + + if (!pattern_stable_release.matcher(min).find() || !pattern_stable_release.matcher(last).find()) { + throw new IllegalArgumentException("VersionCheck: wrong format for min or last version given"); + } + + match = pattern_stable_release.matcher(value); + if (match.find()) { + + switch (correlate(min, last, match.group())){ + case 0: + return UNSUPPORTED_OLD; + case 1: + return SUPPORTED_OLD; + case 2: + return SUPPORTED_LATEST; + default: + return UNSUPPORTED_NEW; + } + + } + + match = pattern_dev_release.matcher(value); + if (match.find()) { + + match = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)").matcher(value); + match.find(); + + if (correlate(min, last, match.group())>0) { + return DEVELOPMENT; + } + else { + return UNSUPPORTED_OLD; + } + + } + + return UNKNOWN; + + } + + //helper + // 0 to less + // 1 in range + // 2 at the top + // 3 above + private static int correlate(String min, String last, String value){ + int min_check = compareVersion(value,min); + int max_check = compareVersion(value,last); + int range_check = compareVersion(min,last); + + switch (range_check) { + case 2: + throw new IllegalArgumentException("Minimum Version higher than Last Version"); + case 1: //min == last + switch (min_check) { + case 0: + return 0; + case 1: + return 2; + default: + return 3; + } + default: + if (max_check >1) return 3; + if (max_check == 1) return 2; + if (min_check < 1) return 0; + return 1; + } + + } + + /** + * @description compare doted formatted Versions + * @param A doted formatted Versions + * @param B doted formatted Versions + * @return 0|1|2 + * 0 = less + * 1 = same + * 2 = more + */ + public static int compareVersion(String A, String B) { + //throw new IllegalArgumentException + if((!A.matches("[0-9]+(\\.[0-9]+)*")) || (!B.matches("[0-9]+(\\.[0-9]+)*"))) throw new IllegalArgumentException("Invalid version format"); + + if (A.contains(".") || B.contains(".")) { + // example 2 vs 1.3 + if (!(A.contains(".") && B.contains("."))) { + if (A.contains(".")) { + return compareVersion(A,B + ".0"); + } + if (B.contains(".")) { + return compareVersion(A + ".0",B); + } + } + + //normal compare + int a = Integer.parseInt(A.substring(0,A.indexOf("."))); + int b = Integer.parseInt(B.substring(0,B.indexOf("."))); + if (a < b) return 0; + if (a == b) return compareVersion(A.substring(A.indexOf(".")+1),B.substring(B.indexOf(".")+1)); + return 2; //if (a > b) + } + else { + int a = Integer.parseInt(A); + int b = Integer.parseInt(B); + if (a < b) return 0; + if (a == b) return 1; + return 2; //if (a > b) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java index 74ac11bc..36135b33 100644 --- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java +++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java @@ -48,7 +48,7 @@ import retrofit2.http.Query; public interface ApiInterface { @GET("version") // gitea version API - Call getGiteaVersion(@Header("Authorization") String token); + Call getGiteaVersion(); @GET("user") // username, full name, email Call getUserInfo(@Header("Authorization") String token); diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml index 258667d0..75ae97e0 100644 --- a/app/src/main/res/layout/fragment_about.xml +++ b/app/src/main/res/layout/fragment_about.xml @@ -191,21 +191,4 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 80ff0a20..dd9ce68d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,6 +20,9 @@ Support the App on Liberapay Become a Patreon + 1.9.0 + 1.10.9 + My Repositories Starred Repositories @@ -514,4 +517,14 @@ Repository removed from watch list Root + Unsupported old version(%1$s) of Gitea detected. Please update to latest stable version. If you continue, the app may not function properly. + Old Gitea version detected, please update to latest stable version + New Gitea version detected! Please UPDATE GitNex! + Gitea version is up to date + Gitea development version + No Gitea detected! + Version Alert + Unsupported Version of Gitea + Cancel + Continue