diff --git a/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java b/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java index 37e137f1e07bfc30a35c7ecb9b9b131b32749b98..d1e48ada97f505d1d6d04627a3a2d7e48f51d35c 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java +++ b/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; @@ -12,7 +13,12 @@ import androidx.navigation.ui.NavigationUI; import com.google.android.material.bottomnavigation.BottomNavigationView; +import java.io.IOException; +import java.security.GeneralSecurityException; + +import fr.nitorac.aurionweb.aurionweb.AurionCred; import fr.nitorac.aurionweb.aurionweb.AurionManager; +import fr.nitorac.aurionweb.security.SecurityManager; import fr.nitorac.aurionweb.update.UpdateManager; public class MainActivity extends AppCompatActivity { @@ -26,11 +32,19 @@ public class MainActivity extends AppCompatActivity { setContentView(R.layout.activity_main); UpdateManager.getInstance().checkUpdates(this); - AurionManager.getInstance().spawnLoginDialog(this); + + try{ + SecurityManager.loadSavedCreds(this); + }catch (GeneralSecurityException | IOException e){ + e.printStackTrace(); + Toast.makeText(this, "Impossible de récupérer les identifiants sauvegardés :(", Toast.LENGTH_LONG).show(); + SecurityManager.creds = new AurionCred(); + } BottomNavigationView navView = findViewById(R.id.nav_view); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); NavigationUI.setupWithNavController(navView, navController); + navView.setOnNavigationItemReselectedListener((ignored) -> {}); } @Override @@ -44,7 +58,11 @@ public class MainActivity extends AppCompatActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.connect_menuitem: - AurionManager.getInstance().spawnLoginDialog(this); + try{ + AurionManager.getInstance().spawnLoginDialog(this); + }catch (Exception e){ + Toast.makeText(this, "Impossible d'afficher la connexion (Erreur : " + e.getLocalizedMessage() + ")", Toast.LENGTH_LONG).show(); + } return true; default: return super.onOptionsItemSelected(item); diff --git a/app/src/main/java/fr/nitorac/aurionweb/StorageManager.java b/app/src/main/java/fr/nitorac/aurionweb/StorageManager.java new file mode 100644 index 0000000000000000000000000000000000000000..a0685c01d2566c5d85721deede2d6250e7e71b9a --- /dev/null +++ b/app/src/main/java/fr/nitorac/aurionweb/StorageManager.java @@ -0,0 +1,51 @@ +package fr.nitorac.aurionweb; + +import android.content.Context; +import android.content.SharedPreferences; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import fr.nitorac.aurionweb.aurionweb.AurionCred; +import fr.nitorac.aurionweb.security.SecurityManager; + +public class StorageManager { + + public final static String MAIN_SHARED_PREF = "main_prefs"; + public static final String SEC_SHARED_PREF = "secstore"; + + private static StorageManager instance; + + public StorageManager(){ + + } + + public AurionCred getCreds(Context c) throws GeneralSecurityException, IOException { + SharedPreferences pref = c.getSharedPreferences(StorageManager.SEC_SHARED_PREF, Context.MODE_PRIVATE); + AurionCred cred = new AurionCred(); + cred.setLogin(pref.getString(AurionCred.LOGIN_KEY, "")); + if(cred.getLogin().isEmpty()){ + return null; + } + cred.setPlainPwd(SecurityManager.getSecurityHelper(c).decrypt(pref.getString(AurionCred.PWD_KEY, ""))); + cred.setRemember(pref.getBoolean(AurionCred.REM_KEY, false)); + return cred; + } + + public void saveCreds(Context c, AurionCred cred) throws GeneralSecurityException, IOException { + SharedPreferences pref = c.getSharedPreferences(StorageManager.SEC_SHARED_PREF, Context.MODE_PRIVATE); + SharedPreferences.Editor edit = pref.edit(); + edit.putString(AurionCred.LOGIN_KEY, cred.getLogin()); + edit.putString(AurionCred.PWD_KEY, SecurityManager.getSecurityHelper(c).encrypt(cred.getPlainPwd())); + edit.putBoolean(AurionCred.REM_KEY, cred.isRemember()); + edit.apply(); + } + + public static StorageManager getInstance(){ + if(instance == null){ + instance = new StorageManager(); + } + + return instance; + } +} diff --git a/app/src/main/java/fr/nitorac/aurionweb/Utils.java b/app/src/main/java/fr/nitorac/aurionweb/Utils.java index c2fb787a8cf36bad30ee21ef003da83214733ec4..fa04ee79a58d75ae24d460cfec96f7a56cc4321f 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/Utils.java +++ b/app/src/main/java/fr/nitorac/aurionweb/Utils.java @@ -10,7 +10,11 @@ import com.google.gson.JsonObject; import org.jsoup.Connection; import org.jsoup.Jsoup; +import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.cert.Certificate; @@ -25,6 +29,7 @@ import javax.net.ssl.TrustManagerFactory; public class Utils { + public final static String BASE_SSL_URL = "https://ranini.iiens.net/aurionweb-check/cert.php?site="; private static SSLContext sslContext; public static Connection wrapSSL(String url) throws GeneralSecurityException, IOException { @@ -32,13 +37,31 @@ public class Utils { .sslSocketFactory(getContextForTrustedCertificates(MainActivity.getInstance().getApplicationContext()).getSocketFactory()); } + // Comme les certificats SSL de cas.ensiie.fr et aurionweb.ensiie.fr sont auto-signés, Android les refuse + // + // Ici on indique à Android qu'on fait confiance à uniquement ces 2 certificats public static SSLContext getContextForTrustedCertificates(Context c) throws GeneralSecurityException, IOException { if(sslContext == null){ CertificateFactory cf = CertificateFactory.getInstance("X.509"); - - Certificate cas = cf.generateCertificate(c.getResources().openRawResource(R.raw.cas_ensiie_fr)); - Certificate aurionweb = cf.generateCertificate(c.getResources().openRawResource(R.raw.aurionweb_ensiie_fr)); + // Fetch certificate from my perso + InputStream casInput; + InputStream aurionInput; + try{ + URLConnection casConn = new URL(BASE_SSL_URL + "cas").openConnection(); + URLConnection aurionConn = new URL(BASE_SSL_URL + "aurion").openConnection(); + casConn.connect(); + aurionConn.connect(); + casInput = new BufferedInputStream(casConn.getInputStream()); + aurionInput = new BufferedInputStream(aurionConn.getInputStream()); + }catch (IOException e){ + e.printStackTrace(); + casInput = c.getResources().openRawResource(R.raw.cas_ensiie_fr); + aurionInput = c.getResources().openRawResource(R.raw.aurionweb_ensiie_fr); + } + + Certificate cas = cf.generateCertificate(casInput); + Certificate aurionweb = cf.generateCertificate(aurionInput); // Create a KeyStore containing our trusted CAs String keyStoreType = KeyStore.getDefaultType(); diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionCred.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionCred.java new file mode 100644 index 0000000000000000000000000000000000000000..518aeae08430231e5f39dc1a64b94c4797c271f5 --- /dev/null +++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionCred.java @@ -0,0 +1,14 @@ +package fr.nitorac.aurionweb.aurionweb; + +import lombok.Data; + +@Data +public class AurionCred { + public static final String LOGIN_KEY = "cred_login"; + public static final String PWD_KEY = "cred_pwd"; + public static final String REM_KEY = "cred_remember"; + + private String login = ""; + private String plainPwd = ""; + private boolean remember = false; +} diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java index 71bed7109a2a0964450a14c6d32a31f9cf31d41b..9b1be1501c68beb4c0f935b1c2add24847e44a00 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java +++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java @@ -2,6 +2,7 @@ package fr.nitorac.aurionweb.aurionweb; import android.content.Context; import android.util.TypedValue; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast; @@ -20,7 +21,9 @@ import java.io.IOException; import java.security.GeneralSecurityException; import fr.nitorac.aurionweb.R; +import fr.nitorac.aurionweb.StorageManager; import fr.nitorac.aurionweb.Utils; +import fr.nitorac.aurionweb.security.SecurityManager; public class AurionManager { @@ -30,12 +33,15 @@ public class AurionManager { } - public boolean checkPassword(String username, String password) { - AurionSession session = new AurionSession(); + public boolean checkPassword(AurionSession session, AurionCred cred) throws GeneralSecurityException { + if(session == null){ + session = new AurionSession(); + } + try { - initConnection(session, username, password); + initConnection(session, cred.getLogin(), cred.getPlainPwd()); return true; - } catch (Exception e) { + } catch (IOException e) { e.printStackTrace(); return false; } @@ -132,26 +138,12 @@ public class AurionManager { return respDoc; } - public void spawnLoginDialog(Context c){ + public void spawnLoginDialog(Context c) { final MaterialDialog dialog = new MaterialDialog(c, new BottomSheet(LayoutMode.MATCH_PARENT)) .title(null, "Connexion AurionWeb") .icon(null, ContextCompat.getDrawable(c, R.drawable.ic_login)) .cancelable(true) .noAutoDismiss() - .positiveButton(null, "CONNEXION", materialDialog -> { - EditText login = materialDialog.getView().findViewById(R.id.loginInput); - EditText pwd = materialDialog.getView().findViewById(R.id.passwordInput); - CheckConnectionTask checkTask = new CheckConnectionTask(c, (res) -> { - if(res){ - Toast.makeText(c, "Connexion réussie !", Toast.LENGTH_LONG).show(); - materialDialog.dismiss(); - }else{ - Toast.makeText(c, "Mauvais mot de passe ou erreur de connexion !", Toast.LENGTH_LONG).show(); - } - }); - checkTask.execute(login.getText().toString().toLowerCase().trim(), pwd.getText().toString().trim()); - return null; - }) .negativeButton(null, "ANNULER", materialDialog -> { materialDialog.dismiss(); return null; @@ -161,6 +153,56 @@ public class AurionManager { // Errk, dirtyyyy, but I can't find any other way to do it DialogCustomViewExtKt.customView(dialog, R.layout.dialog_login, null, false, false, true, true); + final EditText login = dialog.findViewById(R.id.loginInput); + final EditText pwd = dialog.findViewById(R.id.passwordInput); + final CheckBox remember = dialog.findViewById(R.id.rememberMe); + + final StringBuilder savedPwd = new StringBuilder(); + + try{ + AurionCred cred = StorageManager.getInstance().getCreds(c); + if(cred != null){ + login.setText(cred.getLogin()); + savedPwd.append(cred.getPlainPwd()); + pwd.setHint("(aucune modification)"); + remember.setChecked(cred.isRemember()); + } + }catch (Exception e){ + e.printStackTrace(); + Toast.makeText(c, "Erreur : " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); + } + + dialog.positiveButton(null, "CONNEXION", materialDialog -> { + final AurionCred newCred = new AurionCred(); + newCred.setLogin(login.getText().toString().toLowerCase().trim()); + + String tmpPwd = pwd.getText().toString().trim(); + + if(!savedPwd.toString().isEmpty() && tmpPwd.isEmpty()){ + tmpPwd = savedPwd.toString(); + } + + newCred.setPlainPwd(tmpPwd); + newCred.setRemember(remember.isChecked()); + + CheckConnectionTask checkTask = new CheckConnectionTask(c, (res) -> { + if(res){ + Toast.makeText(c, "Connexion réussie !", Toast.LENGTH_LONG).show(); + materialDialog.dismiss(); + SecurityManager.creds = newCred; + try{ + StorageManager.getInstance().saveCreds(c, newCred.isRemember() ? newCred : new AurionCred()); + }catch (Exception e){ + Toast.makeText(c, "Impossible de sauver les paramètres (Erreur : " + e.getLocalizedMessage() + ")", Toast.LENGTH_LONG).show(); + } + }else{ + Toast.makeText(c, "Mauvais mot de passe ou erreur de connexion !", Toast.LENGTH_LONG).show(); + } + }); + checkTask.execute(newCred); + return null; + }); + // Errk, dirtyyyy, workaround to avoid a flickering issue when dialog is sliding dialog.dismiss(); diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/CheckConnectionTask.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/CheckConnectionTask.java index 974ddb5088325ce130d3c84c8d718c2be58324bc..14f40a640c398815156ed419461203c166ecf380 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/CheckConnectionTask.java +++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/CheckConnectionTask.java @@ -8,15 +8,23 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.bottomsheets.BottomSheet; import com.afollestad.materialdialogs.customview.DialogCustomViewExtKt; +import java.security.GeneralSecurityException; + import fr.nitorac.aurionweb.R; -public class CheckConnectionTask extends AsyncTask<String, Void, Boolean> { +public class CheckConnectionTask extends AsyncTask<AurionCred, Void, Boolean> { private MaterialDialog loading; private ConnectionCheck callback; + private AurionSession session; public CheckConnectionTask(Context c, ConnectionCheck callback){ + this(c, new AurionSession(), callback); + } + + public CheckConnectionTask(Context c, AurionSession session, ConnectionCheck callback){ this.callback = callback; + this.session = session; loading = new MaterialDialog(c, new BottomSheet(LayoutMode.WRAP_CONTENT)) .cancelable(false) .cancelOnTouchOutside(false) @@ -40,8 +48,13 @@ public class CheckConnectionTask extends AsyncTask<String, Void, Boolean> { } @Override - protected Boolean doInBackground(String... creds) { - return AurionManager.getInstance().checkPassword(creds[0], creds[1]); + protected Boolean doInBackground(AurionCred... cred) { + try { + return AurionManager.getInstance().checkPassword(session, cred[0]); + } catch (GeneralSecurityException e) { + e.printStackTrace(); + return false; + } } public interface ConnectionCheck { diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/AurionViewFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/AurionViewFragment.java new file mode 100644 index 0000000000000000000000000000000000000000..008e8ee3edeffb153d51bdce8f9d5fb2af550e67 --- /dev/null +++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/AurionViewFragment.java @@ -0,0 +1,30 @@ +package fr.nitorac.aurionweb.fragments; + +import androidx.fragment.app.Fragment; + +import fr.nitorac.aurionweb.aurionweb.AurionManager; +import fr.nitorac.aurionweb.aurionweb.AurionSession; +import fr.nitorac.aurionweb.aurionweb.CheckConnectionTask; +import fr.nitorac.aurionweb.security.SecurityManager; + +public abstract class AurionViewFragment extends Fragment { + + private AurionSession currentSession = new AurionSession(); + + public abstract String getName(); + + public abstract void preload(); + + @Override + public void onResume() { + super.onResume(); + CheckConnectionTask check = new CheckConnectionTask(getContext(), currentSession, res -> { + if(res){ + preload(); + }else{ + AurionManager.getInstance().spawnLoginDialog(getContext()); + } + }); + check.execute(SecurityManager.creds); + } +} diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarFragment.java similarity index 50% rename from app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardFragment.java rename to app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarFragment.java index 0ddc0559bea5248534b0a31cb3944d9aad42f29c..bb8a1e67d8f271f753915701943be4b3e1a19eb9 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardFragment.java +++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarFragment.java @@ -1,4 +1,4 @@ -package fr.nitorac.aurionweb.ui.dashboard; +package fr.nitorac.aurionweb.fragments.calendar; import android.os.Bundle; import android.view.LayoutInflater; @@ -7,29 +7,32 @@ import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; import fr.nitorac.aurionweb.R; +import fr.nitorac.aurionweb.fragments.AurionViewFragment; -public class DashboardFragment extends Fragment { +public class CalendarFragment extends AurionViewFragment { - private DashboardViewModel dashboardViewModel; + private CalendarViewModel calendarViewModel; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - dashboardViewModel = - ViewModelProviders.of(this).get(DashboardViewModel.class); + calendarViewModel = + ViewModelProviders.of(this).get(CalendarViewModel.class); View root = inflater.inflate(R.layout.fragment_calendar, container, false); final TextView textView = root.findViewById(R.id.text_dashboard); - dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { - @Override - public void onChanged(@Nullable String s) { - textView.setText(s); - } - }); + calendarViewModel.getText().observe(getViewLifecycleOwner(), textView::setText); return root; } + + @Override + public String getName() { + return "Calendar"; + } + + @Override + public void preload() { + + } } \ No newline at end of file diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarViewModel.java similarity index 71% rename from app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardViewModel.java rename to app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarViewModel.java index 84c5294ab9787ebaef4ae403c7c862a4772251f3..a6ba66c31ffc2095e3012053e6fed54e66af153d 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardViewModel.java +++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarViewModel.java @@ -1,14 +1,14 @@ -package fr.nitorac.aurionweb.ui.dashboard; +package fr.nitorac.aurionweb.fragments.calendar; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; -public class DashboardViewModel extends ViewModel { +public class CalendarViewModel extends ViewModel { private MutableLiveData<String> mText; - public DashboardViewModel() { + public CalendarViewModel() { mText = new MutableLiveData<>(); mText.setValue("This is dashboard fragment"); } diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeFragment.java similarity index 68% rename from app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeFragment.java rename to app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeFragment.java index 8f3370809543327c937e651f02b18b59d1863b34..559acbdee8df4b3e5f9abd6db3dce7545b56f1a4 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeFragment.java +++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeFragment.java @@ -1,4 +1,4 @@ -package fr.nitorac.aurionweb.ui.home; +package fr.nitorac.aurionweb.fragments.home; import android.os.Bundle; import android.view.LayoutInflater; @@ -7,14 +7,12 @@ import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; import fr.nitorac.aurionweb.R; +import fr.nitorac.aurionweb.fragments.AurionViewFragment; -public class HomeFragment extends Fragment { +public class HomeFragment extends AurionViewFragment { private HomeViewModel homeViewModel; @@ -24,12 +22,17 @@ public class HomeFragment extends Fragment { ViewModelProviders.of(this).get(HomeViewModel.class); View root = inflater.inflate(R.layout.fragment_home, container, false); final TextView textView = root.findViewById(R.id.text_home); - homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { - @Override - public void onChanged(@Nullable String s) { - textView.setText(s); - } - }); + homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText); return root; } + + @Override + public String getName() { + return "Home"; + } + + @Override + public void preload() { + + } } \ No newline at end of file diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeViewModel.java similarity index 90% rename from app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeViewModel.java rename to app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeViewModel.java index 9f8c5f8c519e56342627654d7f6b359f0ee05849..e0b9addb1d182ac89538654db7b46b0f2dba3ea1 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeViewModel.java +++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeViewModel.java @@ -1,4 +1,4 @@ -package fr.nitorac.aurionweb.ui.home; +package fr.nitorac.aurionweb.fragments.home; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsFragment.java similarity index 78% rename from app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsFragment.java rename to app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsFragment.java index f926c6db00442d5e5dc9ebaa111efc0bef49a205..72fc48db7069823523113c5b73dea227a836c55d 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsFragment.java +++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsFragment.java @@ -1,4 +1,4 @@ -package fr.nitorac.aurionweb.ui.notifications; +package fr.nitorac.aurionweb.fragments.notifications; import android.os.Bundle; import android.view.LayoutInflater; @@ -8,13 +8,13 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; import fr.nitorac.aurionweb.R; +import fr.nitorac.aurionweb.fragments.AurionViewFragment; -public class NotificationsFragment extends Fragment { +public class NotificationsFragment extends AurionViewFragment { private NotificationsViewModel notificationsViewModel; @@ -32,4 +32,14 @@ public class NotificationsFragment extends Fragment { }); return root; } + + @Override + public String getName() { + return "Notif"; + } + + @Override + public void preload() { + + } } \ No newline at end of file diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsViewModel.java similarity index 88% rename from app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsViewModel.java rename to app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsViewModel.java index daea70f94234518b31b8f9ec69dce46ef76698c0..56008edaa57f35d808fdb10684de140ff770f5a1 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsViewModel.java +++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsViewModel.java @@ -1,4 +1,4 @@ -package fr.nitorac.aurionweb.ui.notifications; +package fr.nitorac.aurionweb.fragments.notifications; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; diff --git a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPreM.java b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPreM.java index 7a73b260ec3c49cf9f7ab0bd3be82d1dbecab10d..a9ab31dd822d4e2ef3dd5b497690d14563b5d160 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPreM.java +++ b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPreM.java @@ -26,6 +26,8 @@ import javax.crypto.CipherOutputStream; import javax.crypto.spec.SecretKeySpec; import javax.security.auth.x500.X500Principal; +import fr.nitorac.aurionweb.StorageManager; + public class SecurityHelperPreM implements SecurityHelper { private static final String AndroidKeyStore = "AndroidKeyStore"; @@ -60,7 +62,7 @@ public class SecurityHelperPreM implements SecurityHelper { kpg.generateKeyPair(); } - SharedPreferences pref = context.getSharedPreferences(SecurityManager.SEC_SHARED_PREF, Context.MODE_PRIVATE); + SharedPreferences pref = context.getSharedPreferences(StorageManager.SEC_SHARED_PREF, Context.MODE_PRIVATE); String enryptedKeyB64 = pref.getString(SecurityManager.ENCRYPT_KEY, null); if (enryptedKeyB64 == null) { byte[] key = new byte[16]; @@ -108,7 +110,7 @@ public class SecurityHelperPreM implements SecurityHelper { } private Key getSecretKey(Context context) throws GeneralSecurityException, IOException { - SharedPreferences pref = context.getSharedPreferences(SecurityManager.SEC_SHARED_PREF, Context.MODE_PRIVATE); + SharedPreferences pref = context.getSharedPreferences(StorageManager.SEC_SHARED_PREF, Context.MODE_PRIVATE); String enryptedKeyB64 = pref.getString(SecurityManager.ENCRYPT_KEY, null); if(enryptedKeyB64 == null){ throw new InvalidKeyException("Impossible de trouver la clé AES sauvegardée !"); diff --git a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityManager.java b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityManager.java index 0efccaeff166b17440f29211b1e96302e8202957..1950f9ba589598c6ac7d036ceb3d5f321c6347ff 100644 --- a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityManager.java +++ b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityManager.java @@ -6,6 +6,9 @@ import android.os.Build; import java.io.IOException; import java.security.GeneralSecurityException; +import fr.nitorac.aurionweb.StorageManager; +import fr.nitorac.aurionweb.aurionweb.AurionCred; + /** * On utilise une méthode assez compliquée pour stocker le mot de passe Aurionweb * @@ -17,11 +20,16 @@ import java.security.GeneralSecurityException; public class SecurityManager { public static final String KEYSTORE_NAME = "NitAurionWeb"; - public static final String SEC_SHARED_PREF = "secstore"; public static final String ENCRYPT_KEY = "aesKey"; private static SecurityHelper secHelp; + public static AurionCred creds; + + public static void loadSavedCreds(Context c) throws GeneralSecurityException, IOException { + creds = StorageManager.getInstance().getCreds(c); + } + public static SecurityHelper getSecurityHelper(Context c) throws GeneralSecurityException, IOException { if(secHelp == null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { diff --git a/app/src/main/res/layout/dialog_loading.xml b/app/src/main/res/layout/dialog_loading.xml index 305c462076498c58e49c7739b23eb8bc2ad725f6..e2a0967f5e9b448db0110603101ad21714dcf6fe 100644 --- a/app/src/main/res/layout/dialog_loading.xml +++ b/app/src/main/res/layout/dialog_loading.xml @@ -9,6 +9,7 @@ style="?android:attr/progressBarStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginBottom="20dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/dialog_login.xml b/app/src/main/res/layout/dialog_login.xml index 1d135e4f60a3475ed1fd1d19501fec16245796e0..4eb5b733dc7fc54489dbc6964358ebde37b3da2f 100644 --- a/app/src/main/res/layout/dialog_login.xml +++ b/app/src/main/res/layout/dialog_login.xml @@ -16,7 +16,7 @@ android:id="@+id/loginInput" android:layout_width="0dp" android:layout_height="wrap_content" - android:ems="60" + android:ems="150" android:inputType="text" android:hint="prenom.nom" android:layout_marginTop="5dp" @@ -47,8 +47,8 @@ android:id="@+id/passwordInput" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="textWebPassword" - android:hint="••••••••••••"/> + android:ems="250" + android:inputType="textWebPassword"/> </com.google.android.material.textfield.TextInputLayout> diff --git a/app/src/main/res/layout/fragment_calendar.xml b/app/src/main/res/layout/fragment_calendar.xml index 166ab0e9e603c1f230a7b9514d293b963ab2309e..8fd29c3ac0f0c3a4e9249d6b2ca5c74d77d879e6 100644 --- a/app/src/main/res/layout/fragment_calendar.xml +++ b/app/src/main/res/layout/fragment_calendar.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.dashboard.DashboardFragment"> + tools:context=".fragments.calendar.CalendarFragment"> <TextView android:id="@+id/text_dashboard" diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index f3d9b08ffe6101e25c77c5fae7e28bb5dfa11fbd..13bc697876e1910d130ec79c79da7e66958c354f 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.home.HomeFragment"> + tools:context=".fragments.home.HomeFragment"> <TextView android:id="@+id/text_home" diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml index d41793572bb3b8347ec4bced74b7bd4a43bed5d4..258653de4e44054c505565344b86901efe8e67c8 100644 --- a/app/src/main/res/layout/fragment_notifications.xml +++ b/app/src/main/res/layout/fragment_notifications.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.notifications.NotificationsFragment"> + tools:context=".fragments.notifications.NotificationsFragment"> <TextView android:id="@+id/text_notifications" diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index aadbe802166818243e2501bc132466071180e66b..71c664b9209f76b921ef2a4c4246fbe474bcc2b8 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -7,19 +7,19 @@ <fragment android:id="@+id/navigation_home" - android:name="fr.nitorac.aurionweb.ui.home.HomeFragment" + android:name="fr.nitorac.aurionweb.fragments.home.HomeFragment" android:label="@string/title_home" tools:layout="@layout/fragment_home" /> <fragment android:id="@+id/navigation_dashboard" - android:name="fr.nitorac.aurionweb.ui.dashboard.DashboardFragment" + android:name="fr.nitorac.aurionweb.fragments.calendar.CalendarFragment" android:label="@string/title_calendar" tools:layout="@layout/fragment_calendar" /> <fragment android:id="@+id/navigation_notifications" - android:name="fr.nitorac.aurionweb.ui.notifications.NotificationsFragment" + android:name="fr.nitorac.aurionweb.fragments.notifications.NotificationsFragment" android:label="@string/title_notifications" tools:layout="@layout/fragment_notifications" /> </navigation> \ No newline at end of file