diff --git a/Android/.gitignore b/Android/.gitignore new file mode 100644 index 0000000..39fb081 --- /dev/null +++ b/Android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/Android/app/.gitignore b/Android/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/Android/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/Android/app/CMakeLists.txt b/Android/app/CMakeLists.txt new file mode 100644 index 0000000..68b1528 --- /dev/null +++ b/Android/app/CMakeLists.txt @@ -0,0 +1,44 @@ +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html + +# Sets the minimum version of CMake required to build the native library. + +cmake_minimum_required(VERSION 3.4.1) + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. + +add_library( # Sets the name of the library. + native-lib + + # Sets the library as a shared library. + SHARED + + # Provides a relative path to your source file(s). + src/main/jni/native-lib.m ) + +# Searches for a specified prebuilt library and stores the path as a +# variable. Because CMake includes system libraries in the search path by +# default, you only need to specify the name of the public NDK library +# you want to add. CMake verifies that the library exists before +# completing its build. + +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + log ) + +# Specifies libraries CMake should link to your target library. You +# can link multiple libraries, such as libraries you define in this +# build script, prebuilt third-party libraries, or system libraries. + +target_link_libraries( # Specifies the target library. + native-lib + + # Links the target library to the log library + # included in the NDK. + ${log-lib} ) \ No newline at end of file diff --git a/Android/app/build.gradle b/Android/app/build.gradle new file mode 100644 index 0000000..8ba045b --- /dev/null +++ b/Android/app/build.gradle @@ -0,0 +1,41 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 26 + buildToolsVersion "26.0.1" + defaultConfig { + applicationId "mimoja.abfackeln.jetzt.scryptpwgen" + minSdkVersion 15 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { + cppFlags "" + } + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + externalNativeBuild { + cmake { + path "CMakeLists.txt" + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:26.+' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile 'com.android.support:design:26.+' + testCompile 'junit:junit:4.12' +} diff --git a/Android/app/proguard-rules.pro b/Android/app/proguard-rules.pro new file mode 100644 index 0000000..99f2e59 --- /dev/null +++ b/Android/app/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/mimoja/Android/Sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/Android/app/src/androidTest/java/mimoja/abfackeln/jetzt/scryptpwgen/ExampleInstrumentedTest.java b/Android/app/src/androidTest/java/mimoja/abfackeln/jetzt/scryptpwgen/ExampleInstrumentedTest.java new file mode 100644 index 0000000..07507be --- /dev/null +++ b/Android/app/src/androidTest/java/mimoja/abfackeln/jetzt/scryptpwgen/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package mimoja.abfackeln.jetzt.scryptpwgen; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("mimoja.abfackeln.jetzt.scryptpwgen", appContext.getPackageName()); + } +} diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f13328d --- /dev/null +++ b/Android/app/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/java/mimoja/abfackeln/jetzt/scryptpwgen/MainActivity.java b/Android/app/src/main/java/mimoja/abfackeln/jetzt/scryptpwgen/MainActivity.java new file mode 100644 index 0000000..dcbafe2 --- /dev/null +++ b/Android/app/src/main/java/mimoja/abfackeln/jetzt/scryptpwgen/MainActivity.java @@ -0,0 +1,173 @@ +package mimoja.abfackeln.jetzt.scryptpwgen; + +import android.content.ClipboardManager; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.text.InputType; +import android.view.ContextMenu; +import android.view.MenuInflater; +import android.view.textclassifier.TextClassification; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ListView; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.view.MenuItem; +import android.widget.PopupWindow; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class MainActivity extends AppCompatActivity { + + // Used to load the 'native-lib' library on application startup. + static { + System.loadLibrary("native-lib"); + } + + List mKnownSites = null; + ArrayAdapter mAdapter = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + + //Fetch known sites + final SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE); + Set savedSites = sharedPref.getStringSet("knownSites", new HashSet()); + mKnownSites = new ArrayList<>(savedSites); + + //Get Handle to List + ListView siteListView = (ListView) findViewById(R.id.siteList); + registerForContextMenu(siteListView); + mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mKnownSites); + siteListView.setAdapter(mAdapter); + + for (String site : savedSites) { + mAdapter.add(site); + } + + mAdapter.notifyDataSetChanged(); + + // site List + siteListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, final View view, int i, long l) { + + AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); + builder.setTitle("Choose an action") + .setItems(R.array.actions, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + final String chosen = ((TextView)view).getText().toString(); + final EditText userInput = new EditText(MainActivity.this); + userInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + switch (which){ + case 0: + createTextDialog(userInput, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + String masterPasswd = userInput.getText().toString(); + String passwd = generatePassword(chosen, masterPasswd); + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + clipboard.setText(passwd); + Toast.makeText(MainActivity.this, "Password generated", Toast.LENGTH_LONG).show(); + } + }); + break; + case 1: + createTextDialog(userInput, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + String masterPasswd = userInput.getText().toString(); + String passwd = generatePassword(chosen, masterPasswd); + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this); + alertDialogBuilder.setTitle(passwd).setCancelable(true).show(); + Toast.makeText(MainActivity.this, "Password generated", Toast.LENGTH_LONG).show(); + } + }); + + break; + case 2: + mAdapter.remove(chosen); + saveItemList(); + Toast.makeText(MainActivity.this, "Deleted", Toast.LENGTH_LONG).show(); + break; + } + } + }); + builder.create().show(); + + } + }); + + // Add button + FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + final EditText userInput = new EditText(MainActivity.this); + createTextDialog(userInput, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + String site = userInput.getText().toString(); + if(site.length() != 0){ + //Show on screen + if(mKnownSites.contains(site)){ + Toast.makeText(MainActivity.this, "Already cointained", Toast.LENGTH_LONG).show(); + return; + } + mKnownSites.add(site); + saveItemList(); + } + } + }); + } + }); + + } + + public void createTextDialog(EditText userInput, DialogInterface.OnClickListener listener){ + + final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this); + alertDialogBuilder.setView(userInput); + alertDialogBuilder + .setCancelable(false) + .setPositiveButton("Go",listener) + .setNegativeButton("Cancel", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog,int id) { + dialog.dismiss(); + } + } + ); + + AlertDialog alertDialog = alertDialogBuilder.create(); + alertDialog.show(); + userInput.requestFocus(); + } + + public void saveItemList(){ + mAdapter.notifyDataSetChanged(); + + final SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPref.edit(); + editor.clear(); + editor.putStringSet("knownSites", new HashSet<>(mKnownSites)); + editor.commit(); + } + + public native String generatePassword(String site, String password); +} diff --git a/Android/app/src/main/jni/native-lib.m b/Android/app/src/main/jni/native-lib.m new file mode 100644 index 0000000..632efcf --- /dev/null +++ b/Android/app/src/main/jni/native-lib.m @@ -0,0 +1,16 @@ +#include + +JNIEXPORT jstring JNICALL +Java_mimoja_abfackeln_jetzt_scryptpwgen_MainActivity_generatePassword(JNIEnv *env, jobject instance, + jstring site_, + jstring password_) { + const char *site = (*env)->GetStringUTFChars(env, site_, 0); + const char *password = (*env)->GetStringUTFChars(env, password_, 0); + + const char *returnPassword = "Fix me in native-lib.m"; + + (*env)->ReleaseStringUTFChars(env, site_, site); + (*env)->ReleaseStringUTFChars(env, password_, password); + + return (*env)->NewStringUTF(env, returnPassword); +} \ No newline at end of file diff --git a/Android/app/src/main/res/layout/activity_main.xml b/Android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..0f1b5a0 --- /dev/null +++ b/Android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/Android/app/src/main/res/layout/content_main.xml b/Android/app/src/main/res/layout/content_main.xml new file mode 100644 index 0000000..de27c12 --- /dev/null +++ b/Android/app/src/main/res/layout/content_main.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/Android/app/src/main/res/menu/menu_main.xml b/Android/app/src/main/res/menu/menu_main.xml new file mode 100644 index 0000000..7a7c4de --- /dev/null +++ b/Android/app/src/main/res/menu/menu_main.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/Android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..9a078e3 Binary files /dev/null and b/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/Android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c133a0c Binary files /dev/null and b/Android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..efc028a Binary files /dev/null and b/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..bfa42f0 Binary files /dev/null and b/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..3af2608 Binary files /dev/null and b/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..324e72c Binary files /dev/null and b/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..9bec2e6 Binary files /dev/null and b/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..34947cd Binary files /dev/null and b/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/Android/app/src/main/res/values/arrays.xml b/Android/app/src/main/res/values/arrays.xml new file mode 100644 index 0000000..0151d7c --- /dev/null +++ b/Android/app/src/main/res/values/arrays.xml @@ -0,0 +1,8 @@ + + + + Generate password and copy to clipboard + Generate password and show + Remove + + \ No newline at end of file diff --git a/Android/app/src/main/res/values/colors.xml b/Android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..b7014cb --- /dev/null +++ b/Android/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #4081FF + diff --git a/Android/app/src/main/res/values/dimens.xml b/Android/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..59a0b0c --- /dev/null +++ b/Android/app/src/main/res/values/dimens.xml @@ -0,0 +1,3 @@ + + 16dp + diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..c2c51e2 --- /dev/null +++ b/Android/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + SCryptPWGen + Settings + diff --git a/Android/app/src/main/res/values/styles.xml b/Android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..545b9c6 --- /dev/null +++ b/Android/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ + + + + + + + +