0
0
mirror of https://github.com/TrianguloY/UrlChecker.git synced 2024-09-19 20:02:16 +02:00

initialized module views

todo: virustotalmodule
This commit is contained in:
TrianguloY 2020-07-13 16:33:38 +02:00
parent 72d4bb0200
commit b2b0e171d1
22 changed files with 661 additions and 31 deletions

View File

@ -4,7 +4,7 @@ android {
compileSdkVersion 29
defaultConfig {
applicationId "com.trianguloy.urlchecker"
minSdkVersion 10
minSdkVersion 14
targetSdkVersion 29
versionCode 1
versionName "1.0"

View File

@ -9,19 +9,12 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.Black">
<activity android:name="com.trianguloy.urlchecker.Settings">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.trianguloy.urlchecker.OpenLink"
android:theme="@android:style/Theme.DeviceDefault"
android:usesCleartextTraffic="true">
<activity android:name=".MainDialog"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@android:style/Theme.Dialog">
android:theme="@android:style/Theme.DeviceDefault.Dialog">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -32,6 +25,19 @@
<data android:scheme="https" />
</intent-filter>
</activity>
<activity android:name=".old.Settings">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".old.OpenLink"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@android:style/Theme.Dialog">
</activity>
</application>
</manifest>

View File

@ -0,0 +1,55 @@
package com.trianguloy.urlchecker;
import android.content.Context;
import android.content.SharedPreferences;
public abstract class GenericPref<T> {
protected final SharedPreferences prefs;
protected final String prefName;
protected final T defaultValue;
public GenericPref(Context cntx, String filename, String prefName, T defaultValue) {
this.prefName = prefName;
this.defaultValue = defaultValue;
prefs = cntx.getSharedPreferences(filename, Context.MODE_PRIVATE);
}
public abstract T get();
public abstract void set(T value);
// ------------------- Implementations -------------------
static public class Int extends GenericPref<Integer> {
public Int(Context cntx, String filename, String prefName, Integer defaultValue) {
super(cntx, filename, prefName, defaultValue);
}
@Override
public Integer get() {
return prefs.getInt(prefName, defaultValue);
}
@Override
public void set(Integer value) {
prefs.edit().putInt(prefName, value).apply();
}
}
static public class Str extends GenericPref<String> {
public Str(Context cntx, String filename, String prefName, String defaultValue) {
super(cntx, filename, prefName, defaultValue);
}
@Override
public String get() {
return prefs.getString(prefName, defaultValue);
}
@Override
public void set(String value) {
prefs.edit().putString(prefName, value).apply();
}
}
}

View File

@ -0,0 +1,110 @@
package com.trianguloy.urlchecker;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.trianguloy.urlchecker.modules.BaseModule;
import java.util.ArrayList;
import java.util.List;
public class MainDialog extends Activity implements TextWatcher {
private PackageManager pm;
private ComponentName compName;
public void setUrl(String url) {
txt_url.setText(url);
//onChangedUrl(); // not needed, the textwatcher does it
}
public String getUrl() {
return txt_url.getText().toString();
}
// ------------------- data -------------------
private final List<BaseModule> modules = new ArrayList<>();
private TextView txt_url;
private LinearLayout ll_mods;
// ------------------- initialize -------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_dialog);
txt_url = findViewById(R.id.url);
txt_url.addTextChangedListener(this);
ll_mods = findViewById(R.id.mods);
initialize();
setUrl(getOpenUrl());
}
private void initialize() {
modules.addAll(ModuleManager.getEnabled(this));
for (BaseModule module : modules) {
// set title
final String name = module.getName();
if(name != null) {
final TextView title = new TextView(this);
title.setText(name + ":");
ll_mods.addView(title);
}
// set content
final View views = getLayoutInflater().inflate(module.getLayoutBase(), null);
module.setContext(this);
module.initialize(views);
ll_mods.addView(views);
}
}
private String getOpenUrl() {
Uri uri = this.getIntent().getData();
if (uri == null) {
Toast.makeText(this, "No url!!!!", Toast.LENGTH_SHORT).show();
finish();
return null;
}
return uri.toString();
}
// ------------------- url -------------------
private void onChangedUrl() {
for (BaseModule module : modules) {
module.onNewUrl(getUrl());
}
}
// ------------------- TextWatcher -------------------
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
onChangedUrl();
}
}

View File

@ -0,0 +1,47 @@
package com.trianguloy.urlchecker;
import android.content.Context;
import android.content.SharedPreferences;
import com.trianguloy.urlchecker.modules.AsciiModule;
import com.trianguloy.urlchecker.modules.BaseModule;
import com.trianguloy.urlchecker.modules.OpenModule;
import com.trianguloy.urlchecker.modules.RedirectModule;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ModuleManager {
// ------------------- configuration -------------------
private static final Map<String, Class<? extends BaseModule>> modules = new HashMap<>();
static {
modules.put("ascii", AsciiModule.class);
modules.put("redirect", RedirectModule.class);
}
// ------------------- class -------------------
public static List<BaseModule> getEnabled(Context cntx) {
List<BaseModule> enabled = new ArrayList<>();
SharedPreferences prefs = cntx.getSharedPreferences("MM", Context.MODE_PRIVATE);
for (Map.Entry<String, Class<? extends BaseModule>> module : modules.entrySet()) {
if(prefs.getBoolean(module.getKey()+"_en", true)){
try {
enabled.add(module.getValue().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
// always at the end
enabled.add(new OpenModule());
return enabled;
}
}

View File

@ -0,0 +1,36 @@
package com.trianguloy.urlchecker;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
public class UrlUtilities {
static public void openUrlRemoveThis(String url, Context cntx) {
Intent baseIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
PackageManager packageManager = cntx.getPackageManager();
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(baseIntent, Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PackageManager.MATCH_ALL : 0);
List<Intent> intents = new ArrayList<>();
for (ResolveInfo resolveInfo : resolveInfos) {
if (!resolveInfo.activityInfo.packageName.equals(cntx.getPackageName())) {
Intent intent = new Intent(baseIntent);
intent.setPackage(resolveInfo.activityInfo.packageName);
intents.add(intent);
}
}
Intent chooserIntent = Intent.createChooser(intents.remove(0), "Choose app");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[intents.size()]));
cntx.startActivity(chooserIntent);
//startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
}

View File

@ -0,0 +1,51 @@
package com.trianguloy.urlchecker.modules;
import android.view.View;
import android.widget.TextView;
import com.trianguloy.urlchecker.R;
import java.util.ArrayList;
import java.util.List;
public class AsciiModule extends BaseModule {
private TextView txt_ascii;
@Override
public String getName() {
return "Ascii checker";
}
@Override
public int getLayoutBase() {
return R.layout.module_ascii;
}
@Override
public void initialize(View views) {
txt_ascii = views.findViewById(R.id.ascii);
}
@Override
public void onNewUrl(String url) {
List<String> messages = new ArrayList<>();
if (!url.matches("\\A\\p{ASCII}*\\z")) {
messages.add("Warning! Non ascii characters found");
}
if(messages.isEmpty()){
txt_ascii.setText("Good url");
}else {
txt_ascii.setText("");
boolean newline = false;
for (String message : messages) {
if(newline) txt_ascii.append("\n");
newline = true;
txt_ascii.append(message);
}
}
}
}

View File

@ -0,0 +1,23 @@
package com.trianguloy.urlchecker.modules;
import android.content.Context;
import android.view.View;
import com.trianguloy.urlchecker.MainDialog;
public abstract class BaseModule {
protected MainDialog cntx;
public void setContext(MainDialog cntx){
this.cntx = cntx;
}
public abstract String getName();
public abstract int getLayoutBase();
public abstract void initialize(View views);
public abstract void onNewUrl(String url);
}

View File

@ -0,0 +1,56 @@
package com.trianguloy.urlchecker.modules;
import android.content.Intent;
import android.view.View;
import com.trianguloy.urlchecker.R;
import com.trianguloy.urlchecker.UrlUtilities;
public class OpenModule extends BaseModule implements View.OnClickListener {
@Override
public String getName() {
return null;
}
@Override
public int getLayoutBase() {
return R.layout.module_share;
}
@Override
public void initialize(View views) {
views.findViewById(R.id.open).setOnClickListener(this);
views.findViewById(R.id.share).setOnClickListener(this);
}
@Override
public void onNewUrl(String url) {
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.open:
openUrl();
break;
case R.id.share:
shareUrl();
break;
}
}
private void openUrl() {
UrlUtilities.openUrlRemoveThis(cntx.getUrl(), cntx);
}
private void shareUrl() {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, cntx.getUrl());
sendIntent.setType("text/plain");
Intent shareIntent = Intent.createChooser(sendIntent, "Share");
cntx.startActivity(shareIntent);
}
}

View File

@ -0,0 +1,125 @@
package com.trianguloy.urlchecker.modules;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.trianguloy.urlchecker.R;
import com.trianguloy.urlchecker.old.OpenLink;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Stack;
public class RedirectModule extends BaseModule implements View.OnClickListener {
private Button check;
private Button undo;
private Stack<String> urls = new Stack<>();
private boolean expected = false;
@Override
public String getName() {
return "Redirection";
}
@Override
public int getLayoutBase() {
return R.layout.module_redirect;
}
@Override
public void initialize(View views) {
check = views.findViewById(R.id.check);
check.setOnClickListener(this);
undo = views.findViewById(R.id.undo);
undo.setOnClickListener(this);
}
@Override
public void onNewUrl(String url) {
if (expected) {
expected = false;
return;
}
urls.clear();
check.setEnabled(true);
undo.setEnabled(false);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.check:
check();
break;
case R.id.undo:
undo();
break;
}
}
//https://stackoverflow.com/questions/1884230/urlconnection-doesnt-follow-redirect
private void check() {
new Thread(new Runnable() {
public void run() {
String url = cntx.getUrl();
String message = "Unknown error";
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setInstanceFollowRedirects(false); // Make the logic below easier to detect redirections
switch (conn.getResponseCode()) {
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
String location = conn.getHeaderField("Location");
location = URLDecoder.decode(location, "UTF-8");
url = new URL(new URL(url), location).toExternalForm(); // Deal with relative URLs
break;
default:
message = "No redirection, final URL, try to scan now";
url = null;
}
} catch (IOException e) {
e.printStackTrace();
message = "Error when following redirect";
url = null;
} finally {
if (conn != null) {
conn.disconnect();
}
}
final String finalMessage = message;
final String finalUrl = url;
cntx.runOnUiThread(new Runnable() {
public void run() {
if (finalUrl == null) {
Toast.makeText(cntx, finalMessage, Toast.LENGTH_SHORT).show();
check.setEnabled(false);
} else {
urls.push(cntx.getUrl());
expected = true;
cntx.setUrl(finalUrl);
undo.setEnabled(true);
}
}
});
}
}).start();
}
private void undo() {
if (urls.isEmpty()) return;
expected = true;
cntx.setUrl(urls.pop());
check.setEnabled(true);
if (urls.isEmpty()) undo.setEnabled(false);
}
}

View File

@ -1,4 +1,4 @@
package com.trianguloy.urlchecker;
package com.trianguloy.urlchecker.old;
import android.content.Context;
import android.content.pm.PackageManager;
@ -7,6 +7,8 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.trianguloy.urlchecker.R;
import java.util.ArrayList;
/**

View File

@ -1,7 +1,8 @@
package com.trianguloy.urlchecker;
package com.trianguloy.urlchecker.old;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@ -18,6 +19,8 @@ import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.trianguloy.urlchecker.R;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
@ -54,7 +57,7 @@ public class OpenLink extends Activity {
}
url = uri.toString();
txt_url = findViewById(R.id.txt_url);
txt_url = findViewById(R.id.url);
txt_result = findViewById(R.id.txt_result);
btn_redirect = findViewById(R.id.btn_goRedirect);
btn_scan = findViewById(R.id.btn_scan);
@ -175,7 +178,7 @@ public class OpenLink extends Activity {
break;
//DEBUG: just in case
case R.id.txt_url:
case R.id.url:
openUrlInBrowser(url);
break;
}

View File

@ -1,21 +1,25 @@
package com.trianguloy.urlchecker;
package com.trianguloy.urlchecker.old;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import com.trianguloy.urlchecker.R;
public class Settings extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_debug:
@ -23,8 +27,9 @@ public class Settings extends Activity {
break;
}
}
private void openGoogle() {
startActivity(Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")), "Open"));
//startActivity(Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")), "Open"));
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")));
}
}

View File

@ -1,4 +1,4 @@
package com.trianguloy.urlchecker;
package com.trianguloy.urlchecker.old;
import org.json.JSONException;
import org.json.JSONObject;

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.trianguloy.urlchecker.MainDialog">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/url"
style="@android:style/Widget.TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="24sp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/mods"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".OpenLink">
tools:context=".old.OpenLink">
<LinearLayout
android:layout_width="match_parent"
@ -18,7 +18,7 @@
android:orientation="horizontal">
<TextView
android:id="@+id/txt_url"
android:id="@+id/url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"

View File

@ -2,21 +2,21 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".Settings">
tools:context=".old.Settings">
<TextView
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@+id/btn_debug"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="onClick"
android:text="Scan google" />
android:text="Open google" />
</LinearLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/ascii"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/check"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Check" />
<Button
android:id="@+id/undo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Undo" />
</LinearLayout>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/open"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Open" />
<Button
android:id="@+id/share"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Share" />
</LinearLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Open" />
<Button
android:id="@+id/share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Share" />
</LinearLayout>

View File

@ -0,0 +1,7 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.DeviceDefault">
</style>
</resources>