Commit 8f89d5b2 authored by Nastuzzi Samy's avatar Nastuzzi Samy
Browse files

Merge branch 'feature/keyManagement' into develop

parents 04b291a0 8d167833
......@@ -4,17 +4,22 @@ import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.support.v7.app.AlertDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import fr.utc.simde.payutc.tools.HTTPRequest;
import fr.utc.simde.payutc.tools.NFCActivity;
......@@ -24,12 +29,12 @@ import fr.utc.simde.payutc.tools.NemopaySession;
public class MainActivity extends NFCActivity {
private static final String LOG_TAG = "_MainActivity";
private static final String service = "http://assos.utc.fr";
private static Boolean registered = false;
private static final String service = "https://assos.utc.fr";
private static Dialog dialog;
private static NemopaySession nemopaySession;
private static CASConnexion casConnexion;
private static SharedPreferences sharedPreferences;
private static TextView AppConfigText;
private static TextView AppRegisteredText;
......@@ -43,11 +48,26 @@ public class MainActivity extends NFCActivity {
dialog = new Dialog(MainActivity.this);
nemopaySession = new NemopaySession();
casConnexion = new CASConnexion(nemopaySession);
sharedPreferences = getSharedPreferences("payutc", Activity.MODE_PRIVATE);
final String key = sharedPreferences.getString("key", "");
if (!key.equals(""))
setKey(key);
AppConfigText = findViewById(R.id.text_app_config);
AppRegisteredText = findViewById(R.id.text_app_registered);
usernameButton = findViewById(R.id.button_username);
AppRegisteredText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (!nemopaySession.isRegistered())
addKeyDialog();
return false;
}
});
usernameButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
......@@ -61,9 +81,49 @@ public class MainActivity extends NFCActivity {
badgeDialog(idBadge);
}
protected void setRegistered(boolean registered) {
this.registered = registered;
AppRegisteredText.setText(registered ? R.string.app_registred : R.string.app_not_registred);
protected void delKey() {
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.remove("key");
edit.apply();
}
protected void setKey(final String key) {
if (nemopaySession.isRegistered()) {
dialog.errorDialog(getResources().getString(R.string.nemopay_connection), getResources().getString(R.string.nemopay_already_registered));
return;
}
final ProgressDialog loading = ProgressDialog.show(MainActivity.this, getResources().getString(R.string.nemopay_connection), getResources().getString(R.string.nemopay_authentification), true);
loading.setCancelable(false);
new Thread() {
@Override
public void run() {
try {
nemopaySession.loginApp(key);
Thread.sleep(100);
} catch (Exception e) {
Log.e(LOG_TAG, e.getMessage());
}
runOnUiThread(new Runnable() {
@Override
public void run() {
loading.dismiss();
if (nemopaySession.isRegistered()) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("key", key);
editor.apply();
((TextView) findViewById(R.id.text_app_registered)).setText(nemopaySession.getName().substring(0, nemopaySession.getName().length() - (nemopaySession.getName().matches("^.* - ([0-9]{4})([/-])([0-9]{2})\\2([0-9]{2})$") ? 13 : 0)));
}
else
dialog.errorDialog(getResources().getString(R.string.nemopay_connection), getResources().getString(R.string.nemopay_error_registering));
}
});
}
}.start();
}
protected void connectWithCAS(final String username, final String password) throws InterruptedException {
......@@ -119,16 +179,20 @@ public class MainActivity extends NFCActivity {
HTTPRequest request = nemopaySession.loginCas(casConnexion.getTicket(), service);
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
Log.e(LOG_TAG, e.getMessage());
}
runOnUiThread(new Runnable() {
@Override
public void run() {
loading.dismiss();
/*
if (casConnexion.isServiceAdded())
loading.setMessage(getResources().getString(R.string.nemopay_connection));*/
if (!nemopaySession.isConnected())
dialog.errorDialog(getResources().getString(R.string.cas_connection), getResources().getString(R.string.cas_error_service_linking));
else if (!nemopaySession.isRegistered())
keyDialog();
else
Toast.makeText(MainActivity.this, "Tout est bon !", Toast.LENGTH_SHORT).show();
}
});
}
......@@ -140,7 +204,7 @@ public class MainActivity extends NFCActivity {
protected void connectWithBadge(final String idBadge, final String pin) {
dialog.dismiss();
if (registered) {
if (nemopaySession.isRegistered()) {
final ProgressDialog ringProgressDialog = ProgressDialog.show(MainActivity.this, "Connexion ...", "A faire ...", true);
ringProgressDialog.setCancelable(false);
new Thread(new Runnable() {
......@@ -149,6 +213,7 @@ public class MainActivity extends NFCActivity {
try {
Thread.sleep(2000);
} catch (Exception e) {
Log.e(LOG_TAG, e.getMessage());
}
ringProgressDialog.dismiss();
}
......@@ -157,7 +222,7 @@ public class MainActivity extends NFCActivity {
}
protected void badgeDialog(final String idBadge) {
if (!registered) {
if (!nemopaySession.isRegistered()) {
dialog.errorDialog(getResources().getString(R.string.badge_connection), getResources().getString(R.string.badge_app_not_registered));
return;
}
......@@ -171,22 +236,22 @@ public class MainActivity extends NFCActivity {
.setView(pinView)
.setCancelable(true)
.setPositiveButton(R.string.connexion, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
public void onClick(DialogInterface dialogInterface, int id) {
if (pinInput.getText().toString().equals("")) {
Toast.makeText(MainActivity.this, R.string.pin_required, Toast.LENGTH_SHORT).show();
dialog.cancel();
dialogInterface.cancel();
badgeDialog(idBadge);
}
else {
connectWithBadge(idBadge, pinInput.getText().toString());
dialog.cancel();
dialogInterface.cancel();
}
}
})
.setNeutralButton(R.string.no_pin, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
public void onClick(DialogInterface dialogInterface, int id) {
connectWithBadge(idBadge, "0000");
dialog.cancel();
dialogInterface.cancel();
}
});
......@@ -206,31 +271,104 @@ public class MainActivity extends NFCActivity {
.setView(usernameView)
.setCancelable(false)
.setPositiveButton(R.string.connexion, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
public void onClick(DialogInterface dialogInterface, int id) {
if (usernameInput.getText().toString().equals("") || passwordInput.getText().toString().equals("")) {
if (!usernameInput.getText().toString().equals(""))
casConnexion.setUsername(usernameInput.getText().toString());
Toast.makeText(MainActivity.this, R.string.username_and_password_required, Toast.LENGTH_SHORT).show();
dialog.cancel();
dialogInterface.cancel();
connectDialog();
}
else {
try {
connectWithCAS(usernameInput.getText().toString(), passwordInput.getText().toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
Log.e(LOG_TAG, e.getMessage());
}
dialog.cancel();
dialogInterface.cancel();
}
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
public void onClick(DialogInterface dialogInterface, int id) {
dialogInterface.cancel();
}
});
dialog.createDialog(alertDialogBuilder, usernameInput.getText().toString().isEmpty() ? usernameInput : passwordInput);
}
protected void keyDialog() {
final View keyView = getLayoutInflater().inflate(R.layout.dialog_key, null);
final EditText nameInput = keyView.findViewById(R.id.input_name);
final EditText descriptionInput = keyView.findViewById(R.id.input_description);
final String date = new SimpleDateFormat("yyyy/MM/dd", Locale.FRANCE).format(new Date());
nameInput.setText("Téléphone de " + casConnexion.getUsername() + " - " + date);
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilder
.setTitle(R.string.key_dialog)
.setView(keyView)
.setCancelable(false)
.setPositiveButton(R.string.register, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int id) {
if (nameInput.getText().toString().equals("")) {
Toast.makeText(MainActivity.this, R.string.key_name_required, Toast.LENGTH_SHORT).show();
dialogInterface.cancel();
keyDialog();
}
else {
dialogInterface.cancel();
final ProgressDialog loading = ProgressDialog.show(MainActivity.this, getResources().getString(R.string.nemopay_connection), getResources().getString(R.string.nemopay_registering), true);
loading.setCancelable(false);
new Thread() {
@Override
public void run() {
try {
nemopaySession.registerApp(nameInput.getText().toString() + (nameInput.getText().toString().matches("^.* - ([0-9]{4})([/-])([0-9]{2})\\2([0-9]{2})$") ? "" : " - " + date), descriptionInput.getText().toString(), service);
Thread.sleep(100);
} catch (Exception e) {
Log.e(LOG_TAG, e.getMessage());
}
runOnUiThread(new Runnable() {
@Override
public void run() {
loading.dismiss();
if (nemopaySession.getKey().isEmpty())
dialog.errorDialog(getResources().getString(R.string.nemopay_connection), getResources().getString(R.string.nemopay_error_registering));
else
setKey(nemopaySession.getKey());
}
});
}
}.start();
}
}
});
dialog.createDialog(alertDialogBuilder, nameInput);
}
protected void addKeyDialog() {
final View keyView = getLayoutInflater().inflate(R.layout.dialog_key_force, null);
final EditText keyInput = keyView.findViewById(R.id.input_key);
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilder
.setTitle(R.string.key_dialog)
.setView(keyView)
.setCancelable(false)
.setPositiveButton(R.string.register, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int id) {
setKey(keyInput.getText().toString());
}
});
dialog.createDialog(alertDialogBuilder);
}
}
......@@ -6,6 +6,9 @@ package fr.utc.simde.payutc.tools;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
......@@ -14,6 +17,7 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
......@@ -25,7 +29,7 @@ public class HTTPRequest {
private Map<String, String> postArgs;
private Map<String, String> getArgs;
private static Map<String, String> cookies;
private Map<String, String> cookies;
public HTTPRequest(final String url) {
this.url = url;
......@@ -36,6 +40,20 @@ public class HTTPRequest {
this.cookies = new HashMap<String, String>();
}
public static Map<String, String> jsonToMap(String t) throws JSONException {
Map<String, String> map = new HashMap<String, String>();
JSONObject jObject = new JSONObject(t);
Iterator<?> keys = jObject.keys();
while (keys.hasNext()){
String key = (String) keys.next();
String value = jObject.getString(key);
map.put(key, value);
}
return map;
}
public int get() throws IOException {
String get = args2String(this.getArgs, true);
Log.d(LOG_TAG, "get: " + this.url + get);
......@@ -60,6 +78,7 @@ public class HTTPRequest {
this.request = (HttpURLConnection) (new URL(this.url + get)).openConnection();
this.request.setRequestMethod("POST");
this.request.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
this.request.setRequestProperty("charset", "utf-8");
this.request.setRequestProperty("Content-Length", Integer.toString(post.getBytes().length));
this.request.setRequestProperty("Cookie", getCookiesHeader());
this.request.setUseCaches(false);
......@@ -114,6 +133,7 @@ public class HTTPRequest {
this.response = builder.toString();
}
public Map<String, String> getJsonResponse() throws IOException, JSONException { return jsonToMap(response); }
public String getResponse() throws IOException { return response; }
protected String args2String(Map<String, String> args) throws UnsupportedEncodingException { return args2String(args, false); }
......@@ -142,6 +162,14 @@ public class HTTPRequest {
this.postArgs.put(key, value);
}
public Map<String, String> getCookies() {
return this.cookies;
}
public void setCookies(Map<String, String> cookies) {
this.cookies = cookies;
}
synchronized String getCookiesHeader() {
String data = "";
......
package fr.utc.simde.payutc.tools;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import fr.utc.simde.payutc.MainActivity;
import fr.utc.simde.payutc.R;
/**
* Created by Samy on 24/10/2017.
......@@ -14,28 +28,81 @@ import java.util.Map;
public class NemopaySession {
private static final String LOG_TAG = "_NemopaySession";
private static final String url = "https://api.nemopay.net/services/";
private String name;
private String key;
private String session;
private String username;
private Map<String, String> cookies = new HashMap<String, String>();
private final Map<String, String> getArgs = new HashMap<String, String>() {{
put("system_id", "payutc");
}};
public NemopaySession() {
this.name = "";
this.key = "";
this.session = "";
this.username = "";
}
public Boolean isConnected() { return !this.session.isEmpty() && !this.username.isEmpty(); }
public Boolean isRegistered() { return !this.name.isEmpty() && !this.key.isEmpty() && !this.session.isEmpty(); }
public String getName() { return this.name; }
public String getKey() { return this.key; }
public HTTPRequest getCasUrl() throws IOException {
return construct("POSS3", "getCasUrl");
}
public HTTPRequest loginCas(final String ticket, final String service) throws IOException {
return construct("POSS3", "loginCas2", new HashMap<String, String>() {{
public HTTPRequest registerApp(final String name, final String description, final String service) throws IOException, JSONException {
HTTPRequest request = construct("KEY", "registerApplication", new HashMap<String, String>() {{
put("app_url", service);
put("app_name", name);
put("app_desc", description);
}});
if (request.getResponseCode() == 200)
this.key = request.getJsonResponse().get("app_key");
return request;
}
public HTTPRequest loginApp(final String key) throws Exception {
HTTPRequest request = construct("POSS3", "loginApp", new HashMap<String, String>() {{
put("key", key);
}});
Map<String, String> response = request.getJsonResponse();
if (response.containsKey("sessionid") && response.containsKey("name")) {
this.session = response.get("sessionid");
this.name = response.get("name");
this.key = key;
}
else
throw new Exception("Not authentified");
return request;
}
public HTTPRequest loginCas(final String ticket, final String service) throws Exception {
HTTPRequest request = construct("POSS3", "loginCas2", new HashMap<String, String>() {{
put("ticket", ticket);
put("service", service);
}});
Map<String, String> response = request.getJsonResponse();
if (response.containsKey("sessionid") && response.containsKey("username")) {
this.session = response.get("sessionid");
this.username = response.get("username");
}
else
throw new Exception("Not connected");
return request;
}
protected HTTPRequest construct(final String method, final String service) throws IOException { return construct(method, service, new HashMap<String, String>()); }
......@@ -44,8 +111,10 @@ public class NemopaySession {
Log.d(LOG_TAG, "url: " + url + method + "/" + service);
request.setGet(getArgs);
request.setPost(postArgs);
request.setCookies(this.cookies);
request.post();
this.cookies = request.getCookies();
return request;
}
}
<?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/text_key_explication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:text="@string/key_explication"
android:layout_marginBottom="10dp" />
<EditText
android:id="@+id/input_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:inputType="textPersonName"
android:hint="@string/key_name" />
<EditText
android:id="@+id/input_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:inputType="textCapSentences|textAutoCorrect"
android:hint="@string/key_description" />
</LinearLayout>
\ No newline at end of file
<?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/text_key_explication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:text="@string/key_add_explication"
android:layout_marginBottom="10dp" />
<EditText
android:id="@+id/input_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:inputType="text|textEmailAddress"
android:hint="@string/key" />
</LinearLayout>
\ No newline at end of file
......@@ -5,6 +5,7 @@
<string name="app_not_configured">Par défaut</string>
<string name="ok">Ok</string>
<string name="connexion">Se connecter</string>
<string name="register">Enregistrer</string>
<string name="activate">Activer</string>
<string name="pass">Continuer</string>
<string name="erase">Effacer</string>
......@@ -31,7 +32,19 @@
<string name="cas_error_connection">Login et/ou mot de passe non reconnu par le CAS</string>
<string name="cas_error_service_adding">Une erreur a été détectée lors de l\'ajout du service</string>
<string name="cas_error_service_connection">Erreur lors de la connexion au service depuis le CAS</string>
<string name="cas_error_service_linking">Erreur lors de la connexion entre le CAS et le service</string>
<string name="badge_connection">Connexion via badge</string>
<string name="badge_app_not_registered">Il est nécessaire que l\'application soit enregistrée pour permettre la connexion via badge</string>
<string name="nemopay_connection">Connexion à Nemopay</string>
<string name="nemopay_authentification">Authentification de l\'application</string>
<string name="nemopay_registering">Enregistrement de l\'application</string>
<string name="nemopay_already_registered">Application déjà authentifiée</string>
<string name="nemopay_error_registering">Application non enregistrée</string>
<string name="key">Clé d\'application</string>
<string name="key_dialog">Enregistrement de l\'appareil</string>