From 44b13e437717b7523be31c633072a2e1947b8de7 Mon Sep 17 00:00:00 2001 From: "mikgaw@st.amu.edu.pl" Date: Mon, 4 Dec 2023 23:06:59 +0100 Subject: [PATCH] notatki bez del/edit --- .../java/com/example/bsm_notatnik/Login.java | 50 +--- .../example/bsm_notatnik/MainActivity.java | 255 ++++++++++++------ .../java/com/example/bsm_notatnik/Note.java | 31 +++ .../com/example/bsm_notatnik/Register.java | 61 +---- .../com/example/bsm_notatnik/Utility.java | 66 +++++ app/src/main/res/layout/activity_main.xml | 30 ++- .../main/res/layout/create_note_dialog.xml | 23 ++ app/src/main/res/layout/note_item.xml | 25 ++ .../res/layout/password_change_dialog.xml | 2 +- 9 files changed, 345 insertions(+), 198 deletions(-) create mode 100644 app/src/main/java/com/example/bsm_notatnik/Note.java create mode 100644 app/src/main/java/com/example/bsm_notatnik/Utility.java create mode 100644 app/src/main/res/layout/create_note_dialog.xml create mode 100644 app/src/main/res/layout/note_item.xml diff --git a/app/src/main/java/com/example/bsm_notatnik/Login.java b/app/src/main/java/com/example/bsm_notatnik/Login.java index 1a6a629..90584b6 100644 --- a/app/src/main/java/com/example/bsm_notatnik/Login.java +++ b/app/src/main/java/com/example/bsm_notatnik/Login.java @@ -62,7 +62,7 @@ public class Login extends AppCompatActivity { String email, hashedEmail, password; email = String.valueOf(editTextEmail.getText()); - hashedEmail = hashEmail(email); + hashedEmail = Utility.hashEmail(email); password = String.valueOf(editTextPassword.getText()); if (TextUtils.isEmpty(email)){ @@ -91,13 +91,6 @@ public class Login extends AppCompatActivity { return sharedPreferences.contains("user_" + hashedemail); } - private String hashEmail(String email){ - byte[] emailSalt = new byte[16]; - emailSalt = getFirst16BytesOfHash(email); - - return hashCredential(email, emailSalt); - } - private void login(String hashedemail, String password){ SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); String passwordHashFromData = sharedPreferences.getString("user_" + hashedemail, "err"); @@ -105,7 +98,7 @@ public class Login extends AppCompatActivity { byte[] salt = getSaltForUser(hashedemail); - String inputPasswordHash = hashCredential(password, salt); + String inputPasswordHash = Utility.hashCredential(password, salt); assert inputPasswordHash != null; @@ -129,43 +122,4 @@ public class Login extends AppCompatActivity { return Base64.getDecoder().decode(saltFromData); } - private static String hashCredential(String credential, byte[] salt){ - int iteratiions = 1000; - int keyLen = 256; - - KeySpec keySpec = new PBEKeySpec(credential.toCharArray(), salt, iteratiions, keyLen); - try{ - SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); - SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); - byte[] hashedCredential = secretKey.getEncoded(); - return Base64.getEncoder().encodeToString(hashedCredential); - - } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { - e.printStackTrace(); - return null; - } - } - - - private byte[] getFirst16BytesOfHash(String input){ - try { - // Create MessageDigest instance for SHA-256 - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - - // Get the hash value by updating the digest with the input bytes - byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8)); - - // Truncate the hash to the first 16 bytes - byte[] truncatedHash = new byte[16]; - System.arraycopy(hashBytes, 0, truncatedHash, 0, 16); - - return truncatedHash; - } catch (NoSuchAlgorithmException e) { - // Handle the exception (e.g., print an error message) - e.printStackTrace(); - return null; - } - } - - } \ No newline at end of file diff --git a/app/src/main/java/com/example/bsm_notatnik/MainActivity.java b/app/src/main/java/com/example/bsm_notatnik/MainActivity.java index bb8bdad..cc5fdf8 100644 --- a/app/src/main/java/com/example/bsm_notatnik/MainActivity.java +++ b/app/src/main/java/com/example/bsm_notatnik/MainActivity.java @@ -1,39 +1,39 @@ package com.example.bsm_notatnik; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; +import java.util.ArrayList; import java.util.Base64; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; public class MainActivity extends AppCompatActivity { - Button buttonLogout, buttonChangePassword; - + Button buttonLogout, buttonChangePassword, buttonAddNewNote; private static final String SHARED_NAME_CREDENTIALS = "Credentials"; + private static final String SHARED_NOTES_NAME = "Notes"; + + private static final String KEY_NOTE_COUNT = "NoteCount"; + + private static String HASHED_EMAIL = ""; + + private List noteList; + private LinearLayout notesContainer; @Override @@ -43,28 +43,38 @@ public class MainActivity extends AppCompatActivity { Intent intent = getIntent(); String current_username_hashed = intent.getStringExtra("CURRENT_USER_EMAIL_HASH"); + HASHED_EMAIL = current_username_hashed; + + notesContainer = findViewById(R.id.notesContainer); + noteList = new ArrayList<>(); + loadNotesFromPreferences(); + displayNotes(); + + + + buttonLogout = findViewById(R.id.btn_logout); buttonChangePassword = findViewById(R.id.btn_change_password); + buttonAddNewNote = findViewById(R.id.btn_add_note); - buttonLogout.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - logOut(); - } - }); + buttonLogout.setOnClickListener(view -> logOut()); + buttonChangePassword.setOnClickListener(view -> showPasswordChangeDialog(current_username_hashed)); - buttonChangePassword.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - showPasswordChangeDialog(current_username_hashed); - } + buttonAddNewNote.setOnClickListener(view -> { + showAddNewNoteDialog(); }); } + + + + + + private void logOut(){ Toast.makeText(getApplicationContext(), "Logout Successful!", Toast.LENGTH_SHORT).show(); @@ -87,57 +97,87 @@ public class MainActivity extends AppCompatActivity { builder.setTitle("Change Password"); // Set up the positive (OK) button - builder.setPositiveButton("Change", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - // Handle password change logic here - EditText editTextOldPassword = dialogView.findViewById(R.id.editTextOldPassword); - EditText editTextNewPassword = dialogView.findViewById(R.id.editTextNewPassword); - EditText editTextConfirmPassword = dialogView.findViewById(R.id.editTextConfirmPassword); + builder.setPositiveButton("Change", (dialogInterface, i) -> { + // Handle password change logic here + EditText editTextOldPassword = dialogView.findViewById(R.id.editTextOldPassword); + EditText editTextNewPassword = dialogView.findViewById(R.id.editTextNewPassword); + EditText editTextConfirmPassword = dialogView.findViewById(R.id.editTextConfirmPassword); - String oldPassword = editTextOldPassword.getText().toString(); - String newPassword = editTextNewPassword.getText().toString(); - String confirmPassword = editTextConfirmPassword.getText().toString(); + String oldPassword = editTextOldPassword.getText().toString(); + String newPassword = editTextNewPassword.getText().toString(); + String confirmPassword = editTextConfirmPassword.getText().toString(); - if (TextUtils.isEmpty(oldPassword) || TextUtils.isEmpty(newPassword) || TextUtils.isEmpty(confirmPassword)) { - Toast.makeText(MainActivity.this, "Fill out all 3 fields!", Toast.LENGTH_SHORT).show(); - return; - } + if (TextUtils.isEmpty(oldPassword) || TextUtils.isEmpty(newPassword) || TextUtils.isEmpty(confirmPassword)) { + Toast.makeText(MainActivity.this, "Fill out all 3 fields!", Toast.LENGTH_SHORT).show(); + return; + } - if(!validatePassword(newPassword)){ - Toast.makeText(MainActivity.this, "Wrong format of new password!", Toast.LENGTH_SHORT).show(); - return; - } + if(!validatePassword(newPassword)){ + Toast.makeText(MainActivity.this, "Wrong format of new password!", Toast.LENGTH_SHORT).show(); + return; + } - if(!validateOldPassword(hashedEmail, oldPassword)){ - Toast.makeText(MainActivity.this, "Old password not correct!", Toast.LENGTH_SHORT).show(); - return; - } + if(!validateOldPassword(hashedEmail, oldPassword)){ + Toast.makeText(MainActivity.this, "Old password not correct!", Toast.LENGTH_SHORT).show(); + return; + } - // Perform password change validation and logic - if (newPassword.equals(confirmPassword)) { - updatePassword(hashedEmail, newPassword); - Toast.makeText(MainActivity.this, "Password Changed", Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(MainActivity.this, "New passwords don't match!", Toast.LENGTH_SHORT).show(); - return; - } + // Perform password change validation and logic + if (newPassword.equals(confirmPassword)) { + updatePassword(hashedEmail, newPassword); + Toast.makeText(MainActivity.this, "Password Changed", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(MainActivity.this, "New passwords don't match!", Toast.LENGTH_SHORT).show(); } }); // Set up the negative (Cancel) button - builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - dialogInterface.dismiss(); - } - }); + builder.setNegativeButton("Cancel", (dialogInterface, i) -> dialogInterface.dismiss()); // Create and show the AlertDialog AlertDialog alertDialog = builder.create(); alertDialog.show(); } + private void showAddNewNoteDialog(){ + LayoutInflater inflater = getLayoutInflater(); + View dialogView = inflater.inflate(R.layout.create_note_dialog, null); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setView(dialogView); + builder.setTitle("Create new note"); + + builder.setPositiveButton("Save", (dialogInterface, i) -> { + EditText noteTitleEditText = dialogView.findViewById(R.id.noteTitleEditText); + EditText noteContentEditText = dialogView.findViewById(R.id.noteContentEditText); + + String title = noteTitleEditText.getText().toString(); + String content = noteContentEditText.getText().toString(); + + if (!title.isEmpty() && !content.isEmpty()){ + Note note = new Note(); + note.setTitle(title); + note.setContent(content); + + noteList.add(note); + + saveNotesToPreferences(); + createNoteView(note); + } + + Toast.makeText(MainActivity.this, "Note saved!", Toast.LENGTH_SHORT).show(); + }); + + builder.setNegativeButton("Cancel", (dialogInterface, i) -> dialogInterface.dismiss()); + + AlertDialog alertDialog = builder.create(); + alertDialog.show(); + } + + + + + + private boolean validatePassword(String password){ final String PASSWORD_PATTERN = "^.{6,}$"; @@ -151,26 +191,22 @@ public class MainActivity extends AppCompatActivity { SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); - byte[] newSalt = generateSalt(); + byte[] newSalt = Utility.generateSalt(); String newSaltString = Base64.getEncoder().encodeToString(newSalt); editor.putString("salt_" + hashedEmail, newSaltString); - String hashedNewPassword = hashCredential(newPassword, newSalt); + String hashedNewPassword = Utility.hashCredential(newPassword, newSalt); editor.putString("user_" + hashedEmail, hashedNewPassword); editor.apply(); } private boolean validateOldPassword(String hashedEmail, String oldPassword){ byte[] salt = getSaltForUser(hashedEmail); - String hashedOldPassword = hashCredential(oldPassword, salt); + String hashedOldPassword = Utility.hashCredential(oldPassword, salt); String hashedCorrectPassword = getPasswordFromShared(hashedEmail); assert hashedOldPassword != null; - if (hashedOldPassword.equals(hashedCorrectPassword)){ - return true; - } else { - return false; - } + return hashedOldPassword.equals(hashedCorrectPassword); } private byte[] getSaltForUser(String hashedEmail){ @@ -184,29 +220,78 @@ public class MainActivity extends AppCompatActivity { return sharedPreferences.getString("user_" + hashedEmail, "err"); } - private static byte[] generateSalt(){ - SecureRandom random = new SecureRandom(); - byte[] salt = new byte[16]; - random.nextBytes(salt); - return salt; - } + private void saveNote(){ + EditText noteTitleEditText = findViewById(R.id.noteTitleEditText); + EditText noteContentEditText = findViewById(R.id.noteContentEditText); - private static String hashCredential(String credential, byte[] salt){ - int iteratiions = 1000; - int keyLen = 256; + String title = noteTitleEditText.getText().toString(); + String content = noteContentEditText.getText().toString(); - KeySpec keySpec = new PBEKeySpec(credential.toCharArray(), salt, iteratiions, keyLen); - try{ - SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); - SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); - byte[] hashedCredential = secretKey.getEncoded(); - return Base64.getEncoder().encodeToString(hashedCredential); + if (!title.isEmpty() && !content.isEmpty()){ + Note note = new Note(); + note.setTitle(title); + note.setContent(content); - } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { - e.printStackTrace(); - return null; + noteList.add(note); + saveNotesToPreferences(); + + //createNoteView(note); } } + private void saveNotesToPreferences(){ + SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NOTES_NAME, MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + + editor.putInt("notecount_" + HASHED_EMAIL, noteList.size()); + for(int i=0; i + tools:context=".MainActivity" + android:padding="10dp"> + android:orientation="horizontal">