diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460d8b38ac04e3a3224d7c79ef719b1991a9..0000000000000000000000000000000000000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 7d0da68fca4b915f29d68eb40df8db0a46a98a64..5e6c6b07d91046138dd2922db355a06aeb9161fd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,14 +33,12 @@ android { dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) - implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.github.zfman:TimetableView:v2.0.7' - implementation 'com.google.android.material:material:1.3.0' + implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0' - //图像识别 - implementation 'com.rmtheis:tess-two:9.1.0' + implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1' implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.google.code.gson:gson:2.8.6' @@ -50,11 +48,11 @@ dependencies { annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3' testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' //XUI implementation 'com.github.xuexiangjys:XUI:1.1.5' - implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'com.github.bumptech.glide:glide:4.11.0' //友盟移动统计 implementation 'com.umeng.umsdk:common:9.3.6' @@ -69,4 +67,8 @@ dependencies { implementation 'com.github.yalantis:ucrop:2.2.4' //bugly implementation 'com.tencent.bugly:nativecrashreport:3.9.1' + //xUpdate + implementation 'com.github.xuexiangjys:XUpdate:2.1.3' + implementation 'com.zhy:okhttputils:2.6.2' + implementation 'com.github.xuexiangjys.XUtil:xutil-core:2.0.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 05806d511efa5c3a45d675592d2b9021f6936560..3ca2ab0df58778bcbdbe7ae759e3f404dff27fff 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,7 +56,6 @@ - diff --git a/app/src/main/java/top/yvyan/guettable/Gson/InnovationScore.java b/app/src/main/java/top/yvyan/guettable/Gson/InnovationScore.java deleted file mode 100644 index 6a150e5c6c761b3ab67d5075e7e979c21f1fdea3..0000000000000000000000000000000000000000 --- a/app/src/main/java/top/yvyan/guettable/Gson/InnovationScore.java +++ /dev/null @@ -1,148 +0,0 @@ -package top.yvyan.guettable.Gson; - -public class InnovationScore { - private String stid; - private String grade; - private String spno; - private String name; - private String spname; - private String dptno; - private String dptname; - private String classno; - private String msg; - private double pass; - private double lack; - private double lb1; - private double lb21; - private double lb22; - private double lb3; - private String changetype; - - public String getStid() { - return stid; - } - - public void setStid(String stid) { - this.stid = stid; - } - - public String getGrade() { - return grade; - } - - public void setGrade(String grade) { - this.grade = grade; - } - - public String getSpno() { - return spno; - } - - public void setSpno(String spno) { - this.spno = spno; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getSpname() { - return spname; - } - - public void setSpname(String spname) { - this.spname = spname; - } - - public String getDptno() { - return dptno; - } - - public void setDptno(String dptno) { - this.dptno = dptno; - } - - public String getDptname() { - return dptname; - } - - public void setDptname(String dptname) { - this.dptname = dptname; - } - - public String getClassno() { - return classno; - } - - public void setClassno(String classno) { - this.classno = classno; - } - - public String getMsg() { - return msg; - } - - public void setMsg(String msg) { - this.msg = msg; - } - - public double getPass() { - return pass; - } - - public void setPass(double pass) { - this.pass = pass; - } - - public double getLack() { - return lack; - } - - public void setLack(double lack) { - this.lack = lack; - } - - public double getLb1() { - return lb1; - } - - public void setLb1(double lb1) { - this.lb1 = lb1; - } - - public double getLb21() { - return lb21; - } - - public void setLb21(double lb21) { - this.lb21 = lb21; - } - - public double getLb22() { - return lb22; - } - - public void setLb22(double lb22) { - this.lb22 = lb22; - } - - public double getLb3() { - return lb3; - } - - public void setLb3(double lb3) { - this.lb3 = lb3; - } - - public String getChangetype() { - return changetype; - } - - public void setChangetype(String changetype) { - this.changetype = changetype; - } -} diff --git a/app/src/main/java/top/yvyan/guettable/MainActivity.java b/app/src/main/java/top/yvyan/guettable/MainActivity.java index 4799bcf4a0ea2d5efe92b6782f808570fbe29de4..b0da5a9ba5523fe7a8c598a833cb1bce9086bd2e 100644 --- a/app/src/main/java/top/yvyan/guettable/MainActivity.java +++ b/app/src/main/java/top/yvyan/guettable/MainActivity.java @@ -1,5 +1,7 @@ package top.yvyan.guettable; +import static top.yvyan.guettable.widget.WidgetUtil.notifyWidgetUpdate; + import android.annotation.SuppressLint; import android.app.ActivityManager; import android.content.BroadcastReceiver; @@ -45,8 +47,6 @@ import top.yvyan.guettable.fragment.MoreFragment; import top.yvyan.guettable.fragment.PersonFragment; import top.yvyan.guettable.util.BackgroundUtil; -import static top.yvyan.guettable.widget.WidgetUtil.notifyWidgetUpdate; - public class MainActivity extends AppCompatActivity { //小米推送KEY public static final String APP_ID = "2882303761518881128"; @@ -120,8 +120,10 @@ public class MainActivity extends AppCompatActivity { UMRemoteConfig.getInstance().setDefaults(R.xml.cloud_config_parms); UMConfigure.init(this, UMengKey, "Umeng", UMConfigure.DEVICE_TYPE_PHONE, ""); //数据统计 MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO); + //XUpdate初始化 + UpdateApp.initXUpdate(this); // 获取更新 - UpdateApp.check(this, 1); + UpdateApp.check(this); //获取通知 Notification.getNotification(this); diff --git a/app/src/main/java/top/yvyan/guettable/activity/AboutActivity.java b/app/src/main/java/top/yvyan/guettable/activity/AboutActivity.java index 8b1e7dd171bb6bafa3122fb36ca0791bf0b7d73e..8ea3912a42f0096650c9dfb3972edbf7ab88064c 100644 --- a/app/src/main/java/top/yvyan/guettable/activity/AboutActivity.java +++ b/app/src/main/java/top/yvyan/guettable/activity/AboutActivity.java @@ -1,5 +1,7 @@ package top.yvyan.guettable.activity; +import static com.xuexiang.xui.XUI.getContext; + import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -24,8 +26,6 @@ import top.yvyan.guettable.util.BackgroundUtil; import top.yvyan.guettable.util.DialogUtil; import top.yvyan.guettable.util.ToastUtil; -import static com.xuexiang.xui.XUI.getContext; - public class AboutActivity extends AppCompatActivity { @Override @@ -82,36 +82,34 @@ public class AboutActivity extends AppCompatActivity { * 协助测试 */ public void helpTest() { - if (AppUtil.isWifi(Objects.requireNonNull(getContext()))) { + if (SettingData.newInstance(getContext()).isDevelopMode()) { + Intent intent = new Intent(getContext(), HelpTestActivity.class); + startActivity(intent); + } else if (AppUtil.isWifi(Objects.requireNonNull(getContext()))) { DialogUtil.showTextDialog(this, "为了保证测试顺利,请关闭WIFI,连接数据网络后进行测试。"); } else { - if (SettingData.newInstance(getContext()).isDevelopMode()) { - Intent intent = new Intent(getContext(), HelpTestActivity.class); - startActivity(intent); - } else { - ToastUtil.showToast(this, "请不要退出页面或者切换网络,正在获取凭证,最多需要30s,请稍后!"); - new Thread(() -> { - TokenData tokenData = TokenData.newInstance(getContext()); - int n = tokenData.refresh(); - runOnUiThread(() -> { - try { - if (n == 0) { - //获取剪贴板管理器: - ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - // 创建普通字符型ClipData - ClipData mClipData = ClipData.newPlainText("Label", tokenData.getCookie()); - // 将ClipData内容放到系统剪贴板里。 - cm.setPrimaryClip(mClipData); - DialogUtil.showTextDialog(this, "感谢协助,凭证复制成功,您现在可以发送给开发者了!"); - } else { - DialogUtil.showTextDialog(this, "获取失败,请稍后重试。"); - } - } catch (Exception e) { - UMCrash.generateCustomLog(e, "helpTest"); + ToastUtil.showToast(this, "请不要退出页面或者切换网络,正在获取凭证,最多需要30s,请稍后!"); + new Thread(() -> { + TokenData tokenData = TokenData.newInstance(getContext()); + int n = tokenData.refresh(); + runOnUiThread(() -> { + try { + if (n == 0) { + //获取剪贴板管理器: + ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + // 创建普通字符型ClipData + ClipData mClipData = ClipData.newPlainText("Label", tokenData.getCookie()); + // 将ClipData内容放到系统剪贴板里。 + cm.setPrimaryClip(mClipData); + DialogUtil.showTextDialog(this, "感谢协助,凭证复制成功,您现在可以发送给开发者了!"); + } else { + DialogUtil.showTextDialog(this, "获取失败,请稍后重试。"); } - }); - }).start(); - } + } catch (Exception e) { + UMCrash.generateCustomLog(e, "helpTest"); + } + }); + }).start(); } } } \ No newline at end of file diff --git a/app/src/main/java/top/yvyan/guettable/activity/LoginActivity.java b/app/src/main/java/top/yvyan/guettable/activity/LoginActivity.java index 27fcf62102a0a0f0f55781296fc1dbdafd55a843..8004acc8892a41da1e19e41a84dd60b3cb602c06 100644 --- a/app/src/main/java/top/yvyan/guettable/activity/LoginActivity.java +++ b/app/src/main/java/top/yvyan/guettable/activity/LoginActivity.java @@ -4,17 +4,24 @@ import static com.xuexiang.xui.XUI.getContext; import android.app.Activity; import android.content.Intent; +import android.graphics.Color; import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Bundle; import android.text.InputType; import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; +import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import com.umeng.umcrash.UMCrash; import com.xuexiang.xui.widget.textview.supertextview.SuperButton; @@ -111,7 +118,10 @@ public class LoginActivity extends Activity implements View.OnClickListener { String account = etAccount.getText().toString(); String pwd2 = etPwd2.getText().toString(); new Thread(() -> { - String VPNToken = Net.getVPNToken(this); + String VPNToken = null; + if (Net.testNet() != 200) { + VPNToken = Net.getVPNToken(this); + } testCAS(account, pwd2, VPNToken); }).start(); } @@ -126,6 +136,33 @@ public class LoginActivity extends Activity implements View.OnClickListener { } } + /** + * 验证智慧校园密码 OTP Version + * + */ + private void testCASWithOTP(String OTP,String CASCookie, String VPNToken,TokenData tokenData) { + String account = etAccount.getText().toString(); + String pwd2 = etPwd2.getText().toString(); + new Thread(() -> { + runOnUiThread(() -> button.setText("正在认证-手机验证码")); + String MulitFactorAuth = StaticService.VerifyPhoneOTP(this, CASCookie,OTP, VPNToken); + if(MulitFactorAuth.contains("ERROR")) { + if (MulitFactorAuth.equals("ERROR1")) { + showErrorToast(-4); + } else if (MulitFactorAuth.equals("ERROR2")) { + showErrorToast(-2); + } else { + showErrorToast(-8); + } + } else { + tokenData.setCASCookie(CASCookie+"; "+MulitFactorAuth); + tokenData.setBkjwCookie(null); + accountData.setUser(account, null, pwd2, cbRememberPwd.isChecked()); + getInfo(); + } + }).start(); + } + /** * 验证智慧校园密码 * @@ -138,10 +175,37 @@ public class LoginActivity extends Activity implements View.OnClickListener { String CasCookie = StaticService.SSOLogin(this, account, password, VPNToken); if (CasCookie.contains("TGT-")) { TokenData tokenData = TokenData.newInstance(this); - tokenData.setCASCookie(CasCookie); - tokenData.setBkjwCookie(null); - accountData.setUser(account, null, password, cbRememberPwd.isChecked()); - getInfo(); + if(CasCookie.contains("ERROR5")) { + tokenData.setCASCookie(CasCookie.substring(CasCookie.indexOf(";")+1)); + tokenData.setBkjwCookie(null); + fuck2FA(account,password,CasCookie.substring(CasCookie.indexOf(";")+1),VPNToken,tokenData); + if(false) { + String phoneNumber = StaticService.SendPhoneOTP(this, CasCookie.substring(CasCookie.indexOf(";") + 1), account, VPNToken); + if (!phoneNumber.contains("ERROR")) { + runOnUiThread(() -> { + showPhoneOtpDialog(phoneNumber, CasCookie.substring(CasCookie.indexOf(";") + 1), VPNToken, tokenData); + }); + } else { + if (phoneNumber.equals("ERROR1")) { + showErrorToast(-4); + } else if (phoneNumber.equals("ERROR2")) { + showErrorToast(-2); + } else if (phoneNumber.contains("ERROR3")) { + runOnUiThread(() -> { + setEnClick(); + ToastUtil.showToast(this, getResources().getString(R.string.login_fail_phoneOTPSend) + phoneNumber.substring(7)); + }); + } else { + showErrorToast(-8); + } + } + } + } else { + tokenData.setCASCookie(CasCookie); + tokenData.setBkjwCookie(null); + accountData.setUser(account, null, password, cbRememberPwd.isChecked()); + getInfo(); + } } else { if (CasCookie.equals("ERROR1")) { showErrorToast(-4); @@ -154,6 +218,61 @@ public class LoginActivity extends Activity implements View.OnClickListener { }).start(); } + + private void fuck2FA(String account,String password,String CASCookie,String VPNToken,TokenData tokenData) { + try{ + runOnUiThread(() -> button.setText("正在尝试绕过二步验证")); + String MulitFactorAuth = StaticService.fuck2FA(this,password,CASCookie,VPNToken); + if(MulitFactorAuth.contains("ERROR")) { + if (MulitFactorAuth.equals("ERROR1")) { + showErrorToast(-4); + } else if (MulitFactorAuth.equals("ERROR2")) { + showErrorToast(-2); + } else { + showErrorToast(-8); + } + } else { + tokenData.setCASCookie(CASCookie + "; " + MulitFactorAuth); + tokenData.setBkjwCookie(null); + accountData.setUser(account, null, password, cbRememberPwd.isChecked()); + getInfo(); + } + + } catch (Exception ignore) { + return; + } + } + /** + * 显示手机验证码2FA + */ + private void showPhoneOtpDialog(String phoneNumber,String CasCookie,String VPNToken,TokenData tokenData) { + try { + AlertDialog dialog; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + dialog = builder.create(); + dialog.show(); + dialog.setCanceledOnTouchOutside(false); + dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + Window window = dialog.getWindow(); + window.setContentView(R.layout.login_phoneotp); + TextView phoneNumberView = window + .findViewById(R.id.et_phone); + phoneNumberView.setText(phoneNumber); + Button buttonYes = window.findViewById(R.id.btn_text_yes); + buttonYes.setOnClickListener(view -> { + TextView phoneOTP = window + .findViewById(R.id.et_phoneotp); + String OTP=phoneOTP.getText().toString(); + dialog.dismiss(); + testCASWithOTP(OTP,CasCookie,VPNToken,tokenData); + }); + } catch (Exception ignore) { + return; + } + } + /** * 显示登录错误信息 * diff --git a/app/src/main/java/top/yvyan/guettable/baseFun/UpdateApp.java b/app/src/main/java/top/yvyan/guettable/baseFun/UpdateApp.java index 03b90dba320144f294023d33e2f617927372e142..a3dd7e8fe35cf66993fd25b05abe5e5119b65272 100644 --- a/app/src/main/java/top/yvyan/guettable/baseFun/UpdateApp.java +++ b/app/src/main/java/top/yvyan/guettable/baseFun/UpdateApp.java @@ -1,38 +1,14 @@ package top.yvyan.guettable.baseFun; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.net.Uri; -import android.view.Window; -import android.view.WindowManager; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; +import static com.xuexiang.xupdate.entity.UpdateError.ERROR.CHECK_NO_NEW_VERSION; -import androidx.appcompat.app.AlertDialog; +import android.app.Activity; -import com.google.gson.Gson; import com.umeng.cconfig.UMRemoteConfig; +import com.xuexiang.xupdate.XUpdate; +import com.xuexiang.xupdate.utils.UpdateUtils; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.util.Date; -import java.util.Objects; - -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import top.yvyan.guettable.R; -import top.yvyan.guettable.data.GeneralData; -import top.yvyan.guettable.data.SettingData; -import top.yvyan.guettable.util.AppUtil; -import top.yvyan.guettable.util.TimeUtil; +import top.yvyan.guettable.baseFun.service.OKHttpUpdateHttpService; import top.yvyan.guettable.util.ToastUtil; /** @@ -40,140 +16,35 @@ import top.yvyan.guettable.util.ToastUtil; */ public class UpdateApp { - public static void check(Activity activity, int type) { - //服务器更新 - try { - if (type == 2) { - ToastUtil.showToast(activity, "正在检查更新……"); - } - GeneralData generalData = GeneralData.newInstance(activity); - String url = UMRemoteConfig.getInstance().getConfigValue("updateUrl"); - OkHttpClient okHttpClient = new OkHttpClient(); - final Request request = new Request.Builder() - .url(url) - .get() - .build(); - Call call = okHttpClient.newCall(request); - - call.enqueue(new Callback() { - @Override - public void onFailure(@NotNull Call call, @NotNull IOException e) { - activity.runOnUiThread(() -> ToastUtil.showToast(activity, "更新服务器连接失败,请加群检查更新!")); - } - - @Override - public void onResponse(@NotNull Call call, @NotNull Response response) { - try { - String result = Objects.requireNonNull(response.body()).string(); - UpdateInfo updateInfo = new Gson().fromJson(result, UpdateInfo.class); - if (updateInfo.getVersioncode() > AppUtil.getAppVersionCode(activity)) { - if (type == 2) { - //显示弹窗 - activity.runOnUiThread(() -> showUpdateDialog(activity, updateInfo.comm, updateInfo.getVersion(), updateInfo.url)); - } else { - if (SettingData.newInstance(activity).isAppCheckUpdate() || updateInfo.getForce() <= 1) { - if (updateInfo.getForce() <= 2 || generalData.getAppLastUpdateTime() == -1 || TimeUtil.calcDayOffset(new Date(generalData.getAppLastUpdateTime()), new Date()) >= 1) { - // 显示弹窗 - activity.runOnUiThread(() -> showUpdateDialog(activity, updateInfo.comm, updateInfo.getVersion(), updateInfo.url)); - // 刷新时间 - generalData.setAppLastUpdateTime(System.currentTimeMillis()); - } - } - } - } else { - if (type == 2) { - activity.runOnUiThread(() -> ToastUtil.showToast(activity, "已是最新版本!")); - } - } - } catch (Exception e) { - ToastUtil.showToast(activity, "更新服务器连接失败,请加群更新!"); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } - /** - * 显示更新弹窗 + * XUpdate初始化 * - * @param context 上下文 - * @param comm 更新说明 - * @param version 版本 - * @param url 下载链接 + * @param activity activity */ - private static void showUpdateDialog(final Context context, String comm, String version, String url) { - AlertDialog dialog; - AlertDialog.Builder builder = new AlertDialog.Builder(context); - // 创建对话框 - dialog = builder.create(); - dialog.show(); - dialog.setCanceledOnTouchOutside(false); - dialog.setCancelable(false); - dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); - dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); - Window window = dialog.getWindow(); - - window.setContentView(R.layout.update_dialog); - TextView updateVersion = window.findViewById(R.id.tv_updateVersion); - updateVersion.setText(version); - TextView updateComm = window.findViewById(R.id.tv_updateComm); - updateComm.setText(comm); - Button btn_hint_yes = window.findViewById(R.id.btn_hint_yes); - ImageView btn_hint_no = window.findViewById(R.id.imageView_no); - Button btn_hint_addQQ = window.findViewById(R.id.btn_hint_addQQ); - btn_hint_yes.setOnClickListener(arg0 -> { - updateApp(context, url); - dialog.dismiss(); - }); - btn_hint_no.setOnClickListener(arg0 -> dialog.dismiss()); - btn_hint_addQQ.setOnClickListener(arg0 -> { - AppUtil.addQQ(context); - dialog.dismiss(); - }); - } - - private static void updateApp(Context context, String url) { - ToastUtil.showToast(context, "正在打开下载链接,请下载后安装"); - Uri uri = Uri.parse(url == null ? context.getResources().getString(R.string.downloadApp_url) : url); - Intent webIntent = new Intent(); - webIntent.setAction("android.intent.action.VIEW"); - webIntent.setData(uri); - context.startActivity(webIntent); + public static void initXUpdate(Activity activity) { + //设置版本更新出错的监听 + XUpdate.get() + .debug(true) + .isWifiOnly(false) //默认设置只在wifi下检查版本更新 + .isGet(true) //默认设置使用get请求检查版本 + .isAutoMode(false) //默认设置非自动模式,可根据具体使用配置 + .param("versionCode", UpdateUtils.getVersionCode(activity)) //设置默认公共请求参数 + .param("appKey", activity.getPackageName()) + .setOnUpdateFailureListener(error -> { + if (error.getCode() != CHECK_NO_NEW_VERSION) { //对不同错误进行处理 + ToastUtil.showToast(activity, error.toString()); + } + }) + .supportSilentInstall(true) //设置是否支持静默安装,默认是true + .setIUpdateHttpService(new OKHttpUpdateHttpService()) //这个必须设置!实现网络请求功能。 + .init(activity.getApplication()); } - private static class UpdateInfo { - private int versionCode; - private String version; - private int force; - private String redText; - private String comm; - private String url; - - public int getVersioncode() { - return versionCode; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getVersion() { - return version; - } - - public int getForce() { - return force; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getUrl() { - return url; - } + public static void check(Activity activity) { + String url = UMRemoteConfig.getInstance().getConfigValue("XUpdateUrl"); + XUpdate.newBuild(activity) + .supportBackgroundUpdate(true) + .updateUrl(url) + .update(); } } diff --git a/app/src/main/java/top/yvyan/guettable/baseFun/service/OKHttpUpdateHttpService.java b/app/src/main/java/top/yvyan/guettable/baseFun/service/OKHttpUpdateHttpService.java new file mode 100644 index 0000000000000000000000000000000000000000..348692b2101910a10b087d2aa659a173ce7a89c4 --- /dev/null +++ b/app/src/main/java/top/yvyan/guettable/baseFun/service/OKHttpUpdateHttpService.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2018 xuexiangjys(xuexiangjys@163.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.yvyan.guettable.baseFun.service; + +import androidx.annotation.NonNull; + +import com.xuexiang.xupdate.proxy.IUpdateHttpService; +import com.xuexiang.xutil.net.JsonUtil; +import com.zhy.http.okhttp.OkHttpUtils; +import com.zhy.http.okhttp.callback.FileCallBack; +import com.zhy.http.okhttp.callback.StringCallback; +import com.zhy.http.okhttp.request.RequestCall; + +import java.io.File; +import java.util.Map; +import java.util.TreeMap; + +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.Request; + +/** + * 使用okhttp + * + * @author xuexiang + * @since 2018/7/10 下午4:04 + */ +public class OKHttpUpdateHttpService implements IUpdateHttpService { + + private final boolean mIsPostJson; + + public OKHttpUpdateHttpService() { + this(false); + } + + public OKHttpUpdateHttpService(boolean isPostJson) { + mIsPostJson = isPostJson; + } + + + @Override + public void asyncGet(@NonNull String url, @NonNull Map params, final @NonNull Callback callBack) { + OkHttpUtils.get() + .url(url) + .params(transform(params)) + .build() + .execute(new StringCallback() { + @Override + public void onError(Call call, Exception e, int id) { + callBack.onError(e); + } + + @Override + public void onResponse(String response, int id) { + callBack.onSuccess(response); + } + }); + } + + @Override + public void asyncPost(@NonNull String url, @NonNull Map params, final @NonNull Callback callBack) { + //这里默认post的是Form格式,使用json格式的请修改 post -> postString + RequestCall requestCall; + if (mIsPostJson) { + requestCall = OkHttpUtils.postString() + .url(url) + .content(JsonUtil.toJson(params)) + .mediaType(MediaType.parse("application/json; charset=utf-8")) + .build(); + } else { + requestCall = OkHttpUtils.post() + .url(url) + .params(transform(params)) + .build(); + } + requestCall + .execute(new StringCallback() { + @Override + public void onError(Call call, Exception e, int id) { + callBack.onError(e); + } + + @Override + public void onResponse(String response, int id) { + callBack.onSuccess(response); + } + }); + } + + @Override + public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, final @NonNull DownloadCallback callback) { + OkHttpUtils.get() + .url(url) + .tag(url) + .build() + .execute(new FileCallBack(path, fileName) { + @Override + public void inProgress(float progress, long total, int id) { + callback.onProgress(progress, total); + } + + @Override + public void onError(Call call, Exception e, int id) { + callback.onError(e); + } + + @Override + public void onResponse(File response, int id) { + callback.onSuccess(response); + } + + @Override + public void onBefore(Request request, int id) { + super.onBefore(request, id); + callback.onStart(); + } + }); + } + + @Override + public void cancelDownload(@NonNull String url) { + OkHttpUtils.getInstance().cancelTag(url); + } + + private Map transform(Map params) { + Map map = new TreeMap<>(); + for (Map.Entry entry : params.entrySet()) { + map.put(entry.getKey(), entry.getValue().toString()); + } + return map; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/top/yvyan/guettable/data/SettingData.java b/app/src/main/java/top/yvyan/guettable/data/SettingData.java index 3fc4a409a63724256d85af3b704655113805d973..fa7ff4e363112b046482ab36984033be2dd3a84c 100644 --- a/app/src/main/java/top/yvyan/guettable/data/SettingData.java +++ b/app/src/main/java/top/yvyan/guettable/data/SettingData.java @@ -41,10 +41,6 @@ public class SettingData { return sharedPreferences.getBoolean(SettingFragment.SHOW_TOOLS_ON_DAY_CLASS, true); } - public boolean isAppCheckUpdate() { - return sharedPreferences.getBoolean(SettingFragment.APP_CHECK_UPDATE, true); - } - public boolean isDevelopMode() { return sharedPreferences.getBoolean(SettingFragment.DEVELOPER_MODE, false); } diff --git a/app/src/main/java/top/yvyan/guettable/data/TokenData.java b/app/src/main/java/top/yvyan/guettable/data/TokenData.java index d5abe6b0711b4e9f3ac3c55bc80f40e26a517010..9d38596e283275da3c31b58ec43bad961c571091 100644 --- a/app/src/main/java/top/yvyan/guettable/data/TokenData.java +++ b/app/src/main/java/top/yvyan/guettable/data/TokenData.java @@ -7,6 +7,7 @@ import android.content.SharedPreferences; import top.yvyan.guettable.R; import top.yvyan.guettable.service.fetch.Net; import top.yvyan.guettable.service.fetch.StaticService; +import top.yvyan.guettable.util.ToastUtil; public class TokenData { @SuppressLint("StaticFieldLeak") @@ -210,13 +211,32 @@ public class TokenData { return -2; } if (CASCookieStr.contains("TGT-")) { - setCASCookie(CASCookieStr); + if(CASCookieStr.contains("ERROR5")) { + setCASCookie(CASCookieStr.substring(CASCookieStr.indexOf(";")+1)); + return fuck2FA(accountData.getUsername(),accountData.getVPNPwd(),CASCookieStr.substring(CASCookieStr.indexOf(";")+1),VPNToken); + } else { + setCASCookie(CASCookieStr); + } return 0; } else { return -1; } } + private int fuck2FA(String account,String password,String CASCookie,String VPNToken) { + try{ + String MulitFactorAuth = StaticService.fuck2FA(context,password,CASCookie,VPNToken); + if(MulitFactorAuth.contains("ERROR")) { + return -1; + } else { + setCASCookie(CASCookie + "; " + MulitFactorAuth); + } + return 0; + } catch (Exception ignore) { + return 0; + } + } + public void setCASCookie(String CASCookie) { this.CASCookie = CASCookie; editor.putString(CAS_Cookie, CASCookie); diff --git a/app/src/main/java/top/yvyan/guettable/fragment/MoreFragment.java b/app/src/main/java/top/yvyan/guettable/fragment/MoreFragment.java index 29d440a6e4e0cdaf36273506c551f5189f2802f0..21b689127947194e527127f1612d888b7268c202 100644 --- a/app/src/main/java/top/yvyan/guettable/fragment/MoreFragment.java +++ b/app/src/main/java/top/yvyan/guettable/fragment/MoreFragment.java @@ -11,8 +11,6 @@ import androidx.fragment.app.Fragment; import com.umeng.cconfig.UMRemoteConfig; -import java.util.Objects; - import top.yvyan.guettable.R; import top.yvyan.guettable.data.GeneralData; import top.yvyan.guettable.data.SingleSettingData; @@ -21,7 +19,6 @@ import top.yvyan.guettable.moreFun.ExamActivity; import top.yvyan.guettable.moreFun.ExamScoreActivity; import top.yvyan.guettable.moreFun.ExperimentScoreActivity; import top.yvyan.guettable.moreFun.GradesActivity; -import top.yvyan.guettable.moreFun.InnovationScoreActivity; import top.yvyan.guettable.moreFun.LibActivity; import top.yvyan.guettable.moreFun.MoreUrlActivity; import top.yvyan.guettable.moreFun.PlannedCoursesActivity; @@ -55,7 +52,7 @@ public class MoreFragment extends Fragment implements View.OnClickListener { //透明状态栏 View addStatus = view.findViewById(R.id.add_status); ViewGroup.LayoutParams lp = addStatus.getLayoutParams(); - lp.height = lp.height + AppUtil.getStatusBarHeight(Objects.requireNonNull(getContext())); + lp.height = lp.height + AppUtil.getStatusBarHeight(requireContext()); addStatus.setLayoutParams(lp); view.findViewById(R.id.more_test_schedule).setOnClickListener(this); @@ -68,7 +65,6 @@ public class MoreFragment extends Fragment implements View.OnClickListener { view.findViewById(R.id.more_plan_courses).setOnClickListener(this); view.findViewById(R.id.more_cet).setOnClickListener(this); - view.findViewById(R.id.more_innovation_score).setOnClickListener(this); view.findViewById(R.id.more_url_bkjw).setOnClickListener(this); view.findViewById(R.id.more_url_vpn).setOnClickListener(this); @@ -109,7 +105,7 @@ public class MoreFragment extends Fragment implements View.OnClickListener { @Override public void onStart() { super.onStart(); - setBackground(BackgroundUtil.isSetBackground(Objects.requireNonNull(getContext()))); + setBackground(BackgroundUtil.isSetBackground(requireContext())); initData(); } @@ -164,14 +160,6 @@ public class MoreFragment extends Fragment implements View.OnClickListener { intent = new Intent(getContext(), CETActivity.class); startActivity(intent); break; - case R.id.more_innovation_score: - if (generalData.isInternational()) { - DialogUtil.showTextDialog(getContext(), "国际学院教务系统暂无此功能"); - } else { - intent = new Intent(getContext(), InnovationScoreActivity.class); - startActivity(intent); - } - break; case R.id.more_url_bkjw: @@ -181,16 +169,16 @@ public class MoreFragment extends Fragment implements View.OnClickListener { CommFunc.noLoginWebVPN(getActivity()); break; case R.id.more_url_campus: - openBrowser(Objects.requireNonNull(getContext()).getResources().getString(R.string.url_smart_campus)); + openBrowser(requireContext().getResources().getString(R.string.url_smart_campus)); break; case R.id.more_url_lijiang: CommFunc.noLoginWebVPN(getActivity(), - Objects.requireNonNull(getContext()).getResources().getString(R.string.url_lijiang), - Objects.requireNonNull(getContext()).getResources().getString(R.string.url_lijiang_vpn)); + requireContext().getResources().getString(R.string.url_lijiang), + requireContext().getResources().getString(R.string.url_lijiang_vpn)); break; case R.id.more_url_graduation_project: - openBrowser(Objects.requireNonNull(getContext()).getResources().getString(R.string.url_graduation_project)); + openBrowser(requireContext().getResources().getString(R.string.url_graduation_project)); break; case R.id.more_url_index: openBrowser(UMRemoteConfig.getInstance().getConfigValue("guetYvyanTop")); @@ -203,13 +191,13 @@ public class MoreFragment extends Fragment implements View.OnClickListener { case R.id.more_course_arrange: CommFunc.noLoginWebVPN(getActivity(), - Objects.requireNonNull(getContext()).getResources().getString(R.string.url_course_arrange), - Objects.requireNonNull(getContext()).getResources().getString(R.string.url_course_arrange_vpn)); + requireContext().getResources().getString(R.string.url_course_arrange), + requireContext().getResources().getString(R.string.url_course_arrange_vpn)); break; case R.id.more_empty_room: CommFunc.noLoginWebVPN(getActivity(), - Objects.requireNonNull(getContext()).getResources().getString(R.string.url_empty_room), - Objects.requireNonNull(getContext()).getResources().getString(R.string.url_empty_room_vpn)); + requireContext().getResources().getString(R.string.url_empty_room), + requireContext().getResources().getString(R.string.url_empty_room_vpn)); break; case R.id.more_qq_group: intent = new Intent(getContext(), QQGroupActivity.class); diff --git a/app/src/main/java/top/yvyan/guettable/fragment/PersonFragment.java b/app/src/main/java/top/yvyan/guettable/fragment/PersonFragment.java index 3ac8809d4037b788ccd6ec90a748181c686e0f8e..a7a1ba7708c5c2a7ea57805151cd4b5e6d3b32e5 100644 --- a/app/src/main/java/top/yvyan/guettable/fragment/PersonFragment.java +++ b/app/src/main/java/top/yvyan/guettable/fragment/PersonFragment.java @@ -208,7 +208,7 @@ public class PersonFragment extends Fragment implements View.OnClickListener { break; case R.id.person_update: AppUtil.reportFunc(getContext(), getResources().getString(R.string.person_update)); - UpdateApp.check(getActivity(), 2); + UpdateApp.check(getActivity()); break; case R.id.person_download_all: AppUtil.reportFunc(getContext(), getResources().getString(R.string.person_download_all)); diff --git a/app/src/main/java/top/yvyan/guettable/moreFun/InnovationScoreActivity.java b/app/src/main/java/top/yvyan/guettable/moreFun/InnovationScoreActivity.java deleted file mode 100644 index bd7893f421ba466892b7aae76ea9169ebc21a3ed..0000000000000000000000000000000000000000 --- a/app/src/main/java/top/yvyan/guettable/moreFun/InnovationScoreActivity.java +++ /dev/null @@ -1,142 +0,0 @@ -package top.yvyan.guettable.moreFun; - -import android.annotation.SuppressLint; -import android.os.Bundle; -import android.view.View; -import android.widget.TextView; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.constraintlayout.widget.ConstraintLayout; - -import com.xuexiang.xui.widget.button.ButtonView; - -import butterknife.BindView; -import butterknife.ButterKnife; -import top.yvyan.guettable.Gson.BaseResponse; -import top.yvyan.guettable.Gson.InnovationScore; -import top.yvyan.guettable.R; -import top.yvyan.guettable.data.SingleSettingData; -import top.yvyan.guettable.service.IMoreFun; -import top.yvyan.guettable.service.MoreFunService; -import top.yvyan.guettable.service.fetch.StaticService; -import top.yvyan.guettable.util.AppUtil; -import top.yvyan.guettable.util.BackgroundUtil; -import top.yvyan.guettable.util.ToastUtil; - -@SuppressLint("NonConstantResourceId") -public class InnovationScoreActivity extends AppCompatActivity implements View.OnClickListener, IMoreFun { - - @BindView(R.id.state) - TextView innovationScoreState; - @BindView(R.id.title) - TextView title; - @BindView(R.id.innovation_dptName) - TextView innovation_dptName; - @BindView(R.id.innovation_major) - TextView innovation_major; - @BindView(R.id.innovation_grade) - TextView innovation_grade; - @BindView(R.id.innovation_studentNumber) - TextView innovation_studentNumber; - @BindView(R.id.innovation_studentName) - TextView innovation_studentName; - @BindView(R.id.innovation_basicScore) - TextView innovationScore_Basic; - @BindView(R.id.innovation_basicScore_train) - TextView innovationScore_Train; - @BindView(R.id.innovation_basicScore_course) - TextView innovationScore_Course; - @BindView(R.id.innovation_practise) - TextView innovationScore_pratise; - @BindView(R.id.innovation_lack) - TextView innovationScore_Lack; - @BindView(R.id.innovation_btn_update) - ButtonView btn_update_innovationScore; - @BindView(R.id.func_base_constraintLayout) - ConstraintLayout header; - - private BaseResponse innovationScoreBaseResponse; - private MoreFunService moreFunService; - private String cookie; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - SingleSettingData singleSettingData = SingleSettingData.newInstance(getApplicationContext()); - BackgroundUtil.setPageTheme(this, singleSettingData.getThemeId()); - setContentView(R.layout.activity_innovation_score); - ButterKnife.bind(this); - header.getBackground().setAlpha(255); - title.setText(getString(R.string.moreFun_innovation_score)); - BackgroundUtil.setFullAlphaStatus(this); - btn_update_innovationScore.setOnClickListener(this); - AppUtil.reportFunc(getApplicationContext(), getString(R.string.moreFun_innovation_score)); - - moreFunService = new MoreFunService(this, this); - moreFunService.update(); - } - - @Override - public void onClick(View view) { - switch (view.getId()) { - case R.id.back: - finish(); - break; - case R.id.innovation_btn_update: - new Thread(() -> { - runOnUiThread(() -> ToastUtil.showToast(this, "正在更新,请耐心等候")); - int result = StaticService.updateInnovationScore(this, cookie); - if (result == 0) { - moreFunService.update(); - runOnUiThread(() -> ToastUtil.showToast(this, "更新数据成功")); - } else { - runOnUiThread(() -> ToastUtil.showToast(this, "更新失败,请稍后重试")); - } - }).start(); - break; - } - } - - @Override - public int updateData(String cookie) { - this.cookie = cookie; - innovationScoreBaseResponse = StaticService.getInnovationScore(this, cookie); - if (innovationScoreBaseResponse != null) { - return 5; - } - return 1; - } - - @Override - public void updateView(String hint, int state) { - innovationScoreState.setText(hint); - if (state == 5) { - updateView(); - } else if (state == 2 || state == -1 || state == -2 || state == -3) { - View loading = findViewById(R.id.page_loading); - View fail = findViewById(R.id.page_fail); - loading.setVisibility(View.GONE); - fail.setVisibility(View.VISIBLE); - } - } - - private void updateView() { - View wait = findViewById(R.id.innovation_waite); - wait.setVisibility(View.GONE); - InnovationScore innovationScore = innovationScoreBaseResponse.getData(); - innovation_dptName.setText(innovationScore.getDptname()); - innovation_grade.setText(innovationScore.getGrade()); - innovation_major.setText(innovationScore.getSpname()); - innovation_studentName.setText(innovationScore.getName()); - innovation_studentNumber.setText(innovationScore.getStid()); - innovationScore_Basic.setText(String.valueOf(innovationScore.getLb1())); - innovationScore_Course.setText(String.valueOf(innovationScore.getLb21())); - innovationScore_Train.setText(String.valueOf(innovationScore.getLb22())); - innovationScore_pratise.setText(String.valueOf(innovationScore.getLb3())); - innovationScore_Lack.setText(String.valueOf(innovationScore.getLack())); - } - - public void doBack(View view) { - finish(); - } -} \ No newline at end of file diff --git a/app/src/main/java/top/yvyan/guettable/service/fetch/Net.java b/app/src/main/java/top/yvyan/guettable/service/fetch/Net.java index 824b4ad0aa3f2297971dce047e1984f62f9f1f16..86ae9c0053f5f43e130a70cd3cc5e11a8ee349a1 100644 --- a/app/src/main/java/top/yvyan/guettable/service/fetch/Net.java +++ b/app/src/main/java/top/yvyan/guettable/service/fetch/Net.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.res.Resources; import java.io.IOException; -import java.net.HttpCookie; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Date; @@ -119,27 +118,27 @@ public class Net { resources.getString(R.string.user_agent), resources.getString(R.string.SSO_referer), body, - VPNToken == null ? cookie_builder.toString() : VPNToken , + VPNToken == null ? cookie_builder.toString() : VPNToken, "}", resources.getString(R.string.cookie_delimiter), null, null, false, resources.getString(R.string.SSO_context_type)); - if (VPNToken==null && LoginRequest.code == -7) { + if (VPNToken == null && LoginRequest.code == -7) { List cookies = LoginRequest.c.getHeaderFields().get("Set-Cookie"); if (cookies != null) { cookie_builder.append("; "); for (String cookie_resp : cookies) { - cookie_builder.append(cookie_resp.substring(0,cookie_resp.indexOf(";")+1)+" "); + cookie_builder.append(cookie_resp.substring(0, cookie_resp.indexOf(";") + 1)).append(" "); } } - LoginRequest.cookie=cookie_builder.toString(); - LoginRequest.cookie=LoginRequest.cookie.substring(0,LoginRequest.cookie.length()-2); - LoginRequest.code=0; + LoginRequest.cookie = cookie_builder.toString(); + LoginRequest.cookie = LoginRequest.cookie.substring(0, LoginRequest.cookie.length() - 2); + LoginRequest.code = 0; return LoginRequest; } - if(VPNToken != null) { + if (VPNToken != null) { //获取 Cookie 判断是否登录成功 HttpConnectionAndCode VPNGetCookieRequest = Get.get( resources.getString(R.string.vpn_get_cookie) + "&vpn_timestamp=" + new Date().getTime(), @@ -155,7 +154,7 @@ public class Net { null, 10000, null); - return VPNGetCookieRequest; + return new HttpConnectionAndCode(LoginRequest.c, VPNGetCookieRequest.code, VPNGetCookieRequest.comment); } return LoginRequest; } catch (Exception ignored) { @@ -164,6 +163,146 @@ public class Net { return new HttpConnectionAndCode(-5); } + /** + * 获取手机验证码 + * + * @param context context + * @param CASCookie CAS Cookie + * @param account + * @param VPNToken VPNToken + * @return Response + */ + public static HttpConnectionAndCode sendPhoneOTP(Context context, String CASCookie, String account, String VPNToken) { + Resources resources = context.getResources(); + return Post.post( + (VPNToken != null ? resources.getString(R.string.url_SendPhoneOTP_VPN) : resources.getString(R.string.url_SendPhoneOTP)), + null, + resources.getString(R.string.user_agent), + resources.getString(R.string.SSO_referer), + "userName=" + account + "&authCodeTypeName=reAuthDynamicCodeType", + VPNToken == null ? CASCookie : VPNToken, + null, + resources.getString(R.string.cookie_delimiter), + null, + null, + false, + resources.getString(R.string.SSO_context_type)); + } + + /** + * 认证手机验证码 + * + * @param context context + * @param CASCookie CAS Cookie + * @param OTP + * @param VPNToken VPNToken + * @return Response + */ + public static HttpConnectionAndCode verifyPhoneOTP(Context context, String CASCookie, String OTP, String VPNToken) { + Resources resources = context.getResources(); + HttpConnectionAndCode VerifyRequest = Post.post( + (VPNToken != null ? resources.getString(R.string.url_ReAuth_VPN) : resources.getString(R.string.url_ReAuth)), + null, + resources.getString(R.string.user_agent), + resources.getString(R.string.SSO_referer), + "service=http%3A%2F%2Ficampus.guet.edu.cn%2FGuetAccount%2FCasLogin&reAuthType=3&isMultifactor=true&password=&dynamicCode=" + OTP + "&uuid=&answer1=&answer2=&otpCode=", + VPNToken == null ? CASCookie : VPNToken, + null, + resources.getString(R.string.cookie_delimiter), + null, + null, + false, + resources.getString(R.string.SSO_context_type)); + if (VPNToken == null) { + return VerifyRequest; + } else { + HttpConnectionAndCode VPNGetCookieRequest = Get.get( + resources.getString(R.string.vpn_get_cookie) + "&vpn_timestamp=" + new Date().getTime(), + null, + resources.getString(R.string.user_agent), + resources.getString(R.string.url_Authserver_VPN), + VPNToken, + null, + resources.getString(R.string.cookie_delimiter), + null, + null, + null, + null, + 10000, + null); + return new HttpConnectionAndCode(VerifyRequest.c, VerifyRequest.code, VerifyRequest.comment, VPNGetCookieRequest.comment, VerifyRequest.resp_code); + } + } + + /** + * 认证手机验证码 + * + * @param context context + * @param CASCookie CAS Cookie + * @param OTP + * @param VPNToken VPNToken + * @return Response + */ + public static HttpConnectionAndCode fuck2FA(Context context, String password, String CASCookie, String VPNToken) { + Resources resources = context.getResources(); + try { + HttpConnectionAndCode MFAParams = Get.get( + (VPNToken != null ? resources.getString(R.string.url_ReAuth_Param_VPN) : resources.getString(R.string.url_ReAuth_Param)), + null, + resources.getString(R.string.user_agent), + resources.getString(R.string.SSO_referer), + VPNToken == null ? CASCookie : VPNToken, + null, + resources.getString(R.string.cookie_delimiter), + null, + null, + null, + null, + 10000, + null); + if (MFAParams.code != 0) { + return new HttpConnectionAndCode(0); + } + ArrayList listExp = RegularUtil.getAllSatisfyStr(MFAParams.comment, "(?<=\"pwdEncryptSalt\":\")(\\w+)(?=\")"); + String AESKey = listExp.get(0); + HttpConnectionAndCode VerifyRequest = Post.post( + (VPNToken != null ? resources.getString(R.string.url_ReAuth_VPN) : resources.getString(R.string.url_ReAuth)), + null, + resources.getString(R.string.user_agent), + resources.getString(R.string.SSO_referer), + "service=http%3A%2F%2Ficampus.guet.edu.cn%2FGuetAccount%2FCasLogin&reAuthType=2&isMultifactor=true&password=" + URLEncoder.encode(AESUtil.CASEncryption(password, AESKey), "UTF-8") + "&dynamicCode=&uuid=&answer1=&answer2=&otpCode=", + VPNToken == null ? CASCookie : VPNToken, + null, + resources.getString(R.string.cookie_delimiter), + null, + null, + false, + resources.getString(R.string.SSO_context_type)); + if (VPNToken == null) { + return VerifyRequest; + } else { + HttpConnectionAndCode VPNGetCookieRequest = Get.get( + resources.getString(R.string.vpn_get_cookie) + "&vpn_timestamp=" + new Date().getTime(), + null, + resources.getString(R.string.user_agent), + resources.getString(R.string.url_Authserver_VPN), + VPNToken, + null, + resources.getString(R.string.cookie_delimiter), + null, + null, + null, + null, + 10000, + null); + return new HttpConnectionAndCode(VerifyRequest.c, VerifyRequest.code, VerifyRequest.comment, VPNGetCookieRequest.comment, VerifyRequest.resp_code); + } + } catch (Exception ignored) { + + } + return new HttpConnectionAndCode(0); + } + /** * 获取SSO ST令牌 新版CAS * @@ -524,58 +663,6 @@ public class Net { ); } - /** - * 查询创新积分 - * - * @param context context - * @param cookie cookie - * @param isVPN 是否外网 - * @return 操作结果 - */ - public static HttpConnectionAndCode getInnovationScore(Context context, String cookie, boolean isVPN) { - Resources resources = context.getResources(); - return Get.get(UrlReplaceUtil.getUrlByVPN(isVPN, resources.getString(R.string.lan_get_innovationScore)), - null, - resources.getString(R.string.user_agent), - UrlReplaceUtil.getUrlByVPN(isVPN, UrlReplaceUtil.getUrlByInternational(GeneralData.newInstance(context).isInternational(), resources.getString(R.string.lan_referer))), - cookie, - "]}", - null, - resources.getString(R.string.lan_login_success_contain_response_text), - null, - null, - null, - null, - null - ); - } - - /** - * 更新创新积分 - * - * @param context context - * @param cookie cookie - * @param isVPN 是否外网 - * @return 操作结果 - */ - public static HttpConnectionAndCode updateInnovationScore(Context context, String cookie, boolean isVPN) { - Resources resources = context.getResources(); - return Post.post( - UrlReplaceUtil.getUrlByVPN(isVPN, resources.getString(R.string.lan_update_innovationScore)), - null, - resources.getString(R.string.user_agent), - UrlReplaceUtil.getUrlByVPN(isVPN, UrlReplaceUtil.getUrlByInternational(GeneralData.newInstance(context).isInternational(), resources.getString(R.string.lan_referer))), - null, - cookie, - "}", - null, - resources.getString(R.string.lan_login_success_contain_response_text), - null, - null, - null - ); - } - /** * 查询已选课程 diff --git a/app/src/main/java/top/yvyan/guettable/service/fetch/StaticService.java b/app/src/main/java/top/yvyan/guettable/service/fetch/StaticService.java index 37d694b46ae387bdad935344805aa54e1c2053c6..2a8c22cb0303d36922376c5fa026f50cb6b7eb70 100644 --- a/app/src/main/java/top/yvyan/guettable/service/fetch/StaticService.java +++ b/app/src/main/java/top/yvyan/guettable/service/fetch/StaticService.java @@ -23,7 +23,6 @@ import top.yvyan.guettable.Gson.ExamInfo; import top.yvyan.guettable.Gson.ExamScore; import top.yvyan.guettable.Gson.ExperimentScore; import top.yvyan.guettable.Gson.Grades; -import top.yvyan.guettable.Gson.InnovationScore; import top.yvyan.guettable.Gson.LabTable; import top.yvyan.guettable.Gson.PlannedCourse; import top.yvyan.guettable.Gson.Resit; @@ -43,6 +42,102 @@ import top.yvyan.guettable.data.TokenData; public class StaticService { + /** + * 发送手机验证码 + * + * @param context context + * @param CASCookie + * @param account 学号 + * @param VPNToken VPNToken + * @return Phone Number + * ERROR0 : 网络错误 + * ERROR1 : 密码错误 + * ERROR2 : 需要使用外网网址进行访问 + * ERROR3 : 验证码发送CD + */ + public static String SendPhoneOTP(Context context, String CASCookie, String account, String VPNToken) { + HttpConnectionAndCode response = Net.sendPhoneOTP(context, CASCookie, account, VPNToken); + if (response.code != 0) { + if (response.code == -5) { + return "ERROR2"; + } + return "ERROR0"; + } else { + if (response.comment.contains("success")) { + int PhoneIndex = response.comment.indexOf("\"mobile\":\"") + 10; + return response.comment.substring(PhoneIndex, PhoneIndex + 11); + } + if (response.comment.contains("code_time_fail")) { + int MessageIndex = response.comment.indexOf("\"returnMessage\":\"") + 17; + String ErrorMessage = response.comment.substring(MessageIndex); + return "ERROR3;" + ErrorMessage.substring(0, ErrorMessage.indexOf("\"")); + } + return "ERROR0"; + } + } + + public static String fuck2FA(Context context, String Password,String CASCookie, String VPNToken) { + HttpConnectionAndCode response = Net.fuck2FA(context, Password,CASCookie, VPNToken); + if (response.code != 0) { + if (response.code == -5) { + return "ERROR2"; + } + return "ERROR0"; + } else { + if (response.comment.contains("reAuth_success")) { + if (VPNToken == null) { + return response.cookie; + } else { + String MultiFactorCookie = response.cookie.substring(response.cookie.indexOf("MULTIFACTOR_USERS")); + int CookieEnd = MultiFactorCookie.indexOf(";"); + if (CookieEnd >= 0) { + return MultiFactorCookie.substring(0, CookieEnd); + } else { + return MultiFactorCookie; + } + } + } + return "ERROR1"; + } + } + + /** + * 发送手机验证码 + * + * @param context context + * @param CASCookie + * @param OTP OTP手机验证码 + * @param VPNToken VPNToken + * @return 多因素身份验证令牌Cookie + * ERROR0 : 网络错误 + * ERROR1 : 密码错误 + * ERROR2 : 需要使用外网网址进行访问 + */ + public static String VerifyPhoneOTP(Context context, String CASCookie, String OTP, String VPNToken) { + HttpConnectionAndCode response = Net.verifyPhoneOTP(context, CASCookie, OTP, VPNToken); + if (response.code != 0) { + if (response.code == -5) { + return "ERROR2"; + } + return "ERROR0"; + } else { + if (response.comment.contains("reAuth_success")) { + if (VPNToken == null) { + return response.cookie; + } else { + String MultiFactorCookie = response.cookie.substring(response.cookie.indexOf("MULTIFACTOR_USERS")); + int CookieEnd = MultiFactorCookie.indexOf(";"); + if (CookieEnd >= 0) { + return MultiFactorCookie.substring(0, CookieEnd); + } else { + return MultiFactorCookie; + } + } + } + return "ERROR1"; + } + } + /** * 获取SSO登录CasCookie * @@ -54,6 +149,7 @@ public class StaticService { * ERROR0 : 网络错误 * ERROR1 : 密码错误 * ERROR2 : 需要使用外网网址进行访问 + * ERROR5 : 2FA Needed */ public static String SSOLogin(Context context, String account, String password, String VPNToken) { HttpConnectionAndCode response = Net.getCASToken(context, account, password, VPNToken); @@ -63,9 +159,13 @@ public class StaticService { } return "ERROR0"; } else { - if(VPNToken == null) { + if (VPNToken == null) { String Cookie = response.cookie; if (Cookie.contains("TGT-")) { + String Location = response.c.getHeaderField("location"); + if (Location.contains("reAuthLoginView.do")) { + return "ERROR5;" + Cookie; + } return Cookie; } else { return "ERROR1"; @@ -73,7 +173,11 @@ public class StaticService { } else { String Cookie = response.comment; if (Cookie.contains("TGT-")) { - return Cookie; + String Location = response.c.getHeaderField("location"); + if (Location.contains("reAuthLoginView.do")) { + return "ERROR5;" + Cookie; + } + return Cookie; } else { return "ERROR1"; } @@ -103,7 +207,7 @@ public class StaticService { } return "ERROR2"; } - if(response.cookie.contains("refresh")) { + if (response.cookie.contains("refresh")) { return "ERROR1"; } return "ERROR0"; @@ -594,47 +698,6 @@ public class StaticService { } } - /** - * 查询创新积分 - * - * @param context context - * @param cookie cookie - * @return 操作结果 - */ - public static BaseResponse getInnovationScore(Context context, String cookie) { - HttpConnectionAndCode httpConnectionAndCode = Net.getInnovationScore(context, cookie, TokenData.isVPN); - if (httpConnectionAndCode.comment != null) { - BaseResponse result; - try { - result = new Gson().fromJson(httpConnectionAndCode.comment.replaceAll("[\\[\\]]", ""), new TypeToken>() { - }.getType()); - } catch (Exception ignored) { - return null; - } - return result; - } else { - return null; - } - } - - /** - * 更新创新积分 - * - * @param context context - * @param cookie cookie - * @return 更新结果 - * -1 更新失败 - * 0 更新成功 - */ - public static int updateInnovationScore(Context context, String cookie) { - HttpConnectionAndCode httpConnectionAndCode = Net.updateInnovationScore(context, cookie, TokenData.isVPN); - String comment = httpConnectionAndCode.comment; - if (comment != null && comment.contains("操作成功")) { - return 0; - } - return -1; - } - /** * 查询已选课程 * diff --git a/app/src/main/res/drawable/btn_confirm.xml b/app/src/main/res/drawable/btn_confirm.xml deleted file mode 100644 index 256ca24402b2f08fa1f1d7ebbedbb3f364517713..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/btn_confirm.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/btn_ignore.xml b/app/src/main/res/drawable/btn_ignore.xml deleted file mode 100644 index 347d69cfc5f6bd53b09fd4959982ee6eb26ec5b8..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/btn_ignore.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/d_shengji.png b/app/src/main/res/drawable/d_shengji.png deleted file mode 100644 index b397f676cded3fd7165190baebc92a87d7b0fdbc..0000000000000000000000000000000000000000 Binary files a/app/src/main/res/drawable/d_shengji.png and /dev/null differ diff --git a/app/src/main/res/drawable/m_fail.xml b/app/src/main/res/drawable/m_fail.xml deleted file mode 100644 index 500b3f08b8b68c60c7f56529d16e45eb02cfc340..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/m_fail.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/m_innovation_score.xml b/app/src/main/res/drawable/m_innovation_score.xml deleted file mode 100644 index a32f15a4c3ae8eeaa471705c0c885a492b369ed8..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/m_innovation_score.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/m_loading.xml b/app/src/main/res/drawable/m_loading.xml deleted file mode 100644 index c03c930b71e78e609a12038107f44214eb638c43..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/m_loading.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_help_test.xml b/app/src/main/res/layout/activity_help_test.xml index c212a9093c93921331cbc605821c6734f61f9014..5b2965db3c364850dc668d3cb7e1fce1f9472657 100644 --- a/app/src/main/res/layout/activity_help_test.xml +++ b/app/src/main/res/layout/activity_help_test.xml @@ -34,7 +34,6 @@ app:layout_constraintGuide_percent="0.5" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index c4c25edc7416bcc6f9654fc5843f72df01d8c9f4..1488252857b117e4efe5aa126190410e5969bbe0 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -164,7 +164,6 @@ app:layout_constraintTop_toTopOf="parent"> diff --git a/app/src/main/res/layout/activity_q_q_group.xml b/app/src/main/res/layout/activity_q_q_group.xml index 01c5c3c1cecc00a6361c10ebcea5243cde6ee27a..561c83205726578d3324595e9cd74eaa695550c7 100644 --- a/app/src/main/res/layout/activity_q_q_group.xml +++ b/app/src/main/res/layout/activity_q_q_group.xml @@ -131,7 +131,6 @@ android:background="@color/xui_config_color_gray_9" /> @@ -144,7 +143,6 @@ app:layout_constraintGuide_begin="60dp" /> + - - - - + tools:ignore="UselessLeaf"> @@ -405,7 +377,6 @@ android:orientation="vertical"> diff --git a/app/src/main/res/layout/login_phoneotp.xml b/app/src/main/res/layout/login_phoneotp.xml new file mode 100644 index 0000000000000000000000000000000000000000..ddf08e09df91c16ff2add6c2980efe3ad1a6e0a7 --- /dev/null +++ b/app/src/main/res/layout/login_phoneotp.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +