Skip to content

Commit

Permalink
Fix Xiaohang PPP (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelly9373 committed Nov 12, 2018
1 parent 6255f69 commit 93821c8
Showing 1 changed file with 185 additions and 3 deletions.
188 changes: 185 additions & 3 deletions docs/team/kelly9373.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ This section shows my contribution to the LoanBook's development.

** added censoring function in Nric, Phone and Email class to enable hiding sensitive information feature in LoanCard UI. (Pull request https://github.com/CS2103-AY1819S1-F10-2/main/pull/125[#125])

* *Code Contributed*: https://nus-cs2103-ay1819s1.github.io/cs2103-dashboard/#=undefined&search=xiaohang&sort=displayName&since=2018-09-12&until=2018-11-11&timeframe=day&reverse=false&repoSort=true[Reposense]

* *Other contributions*:

** Project management:
Expand Down Expand Up @@ -93,14 +95,194 @@ This section shows my contribution to the LoanBook's development.

== Contributions to the User Guide

|===
This section shows the contributions I made to the User Guide. The following instructions show how to use the send email functionality.
|===

=== Check your email: `checkemail`

Checks whether you have set your email or not, and displays the censored email address if you have set it before. +
[big]#*Format*: `checkemail`#

=== Set your email: `setemail`

Sets the email address to send reminder emails from. +
[big]#*Format*: `setemail e/NEWEMAIL x/PASSWORDFORAPP`#

[big red]#List of Parameters#:

`e/NEWEMAIL`: The new user email that you want to set to the app. +
`x/PASSWORDFORAPP`: The password you set for the app. Not your email password.

Some things to take note of for first time users:

* `NEWEMAIL` cannot the same as the user email you have already set to the app.
* `NEWEMAIL` must be a valid Gmail address.

[NOTE]
Only Gmail is accepted!

Examples:

* `setemail e/\new.email@gmail.com x/a12345`

=== Send reminder email: `remind`

Sends a reminder email to the customer. +
[big]#*Format*: `remind pw/EMAILPASSWORD id/LOAN_ID`#

[big red]#List of Parameters#:

`pw/PASSWORD`: Password of the email address you are sending the messages from. +
`id/LOAN_ID`: LoanID of the loan you want to remind +

* `LOANID` is the ID of the loan, not the index.
* `EMAILPASSWORD` must be correct.

[NOTE]
*[IMPORTANT] Before using this command, please go to https://www.google.com/settings/security/lesssecureapps[Less Secure Apps] , enable it and restart the app! [red]#However! If your help page does not respond when enabling, please copy this link: \https://www.google.com/settings/security/lesssecureapps and access it in your browser. Then enable the less secure app setting and refresh the setting page!#* +
[NOTE]
*[IMPORTANT] Please do not connect to eduroam network when using this functionality!*

include::../UserGuide.adoc[tag=sendemail]
Examples:

* `remind pw/samplepassword id/0`

== Contributions to the Developer Guide

|===
This section shows the contributions I made to the Developer Guide. The following instructions show how to the send email functionality is implemented.
|===

=== Hide private information

Users must provide some important and personal information when adding a loan, e.g. `Nric`, so it is our responsibility to protect their privacy.

As a result, we have added a new feature to hide the private information from the Window. +
Example: The customer's `Nric` as stored in the database is `Nric: T0248272F`, but our `LoanCard` will only show `Nric: Txxxxx72F`.

image::LoanListPanelView.png[]

==== Current implementation

Hidden private information is facilitated by an interface called `Censor`. It is implemented by classes `Nric`, `Phone` and `Email`.

When showing a new loan, it will do the following operations:

* `LoanCard#LoanCard()` -- the constructor will assign values to each of the labels shown in the LoanCard.

* `Nric#getCensored()` -- censor the Nric value and hide the first five digital numbers. Then it returns the censored String.

* `Nric#doCensoring(int length)` -- Take in the length of the Nric String and return the censored part ("x" part) according to the length.

* `Phone#getCensored()` -- censor the phone number and hide the first five digital numbers. Then it returns the censored String.

* `Phone#doCensoring(int length)` -- Take in the length of the Phone String and return the censored part ("x" part) according to the length.

* `Email#getCensored()` -- censor the email address and hide every characters except the last two characters in the local-part and the domain.

* `Email#doCensoring(int length)` -- Take in the length of the Email String and return the censored part ("x" part) according to the length.

Given below is an example usage scenario and how this mechanism behaves at each step.

**Step1.** The user adds a new loan to the LoanBook. A new `LoanCard` object will be created. +
The `LoanCard` object will contain information on the loan: `LoanID`, `BikeID`, `Name`, `Nric`, `Phone`, `Email`, `LoanRate` and `LoanTime`.

**Step2.** Assign the value of each of the components to their corresponding labels. +
For example: `name.setText(loan.getName().value);` will directly assign the name String of this loan to the `name` label. +

However, the values of `Nric`, `Phone` and `Email` need censoring before assigning their values, so they will call their own `getCensored()` method in their class. +
`getCensored()` in each of these class will call their corresponding `doCensoring(int)` method. Then combine the censored part and remain part and return. +
For example: `phone.setText(loan.getPhone().getCensored().value);` will censor the value of the phone String of this loan and then assign the censored value to the `phone` label.

The following sequence diagram shows how this operation works:

image::HideInfoSequenceDiagrams.png[]

==== Design Considerations

**Aspect: How to execute getCensored() and doCensoring(int)**

* **Alternative 1 (current choice)**: each class implements from `Censor` interface.
** Pros: Easy to implement.

* **Alternative 2**: `Loan` class implements from `Censor` interface.
** Cons: The method might be bulky.

=== Send Reminder Email feature

==== Current Implementation

The email sending mechanism is supported by the https://docs.oracle.com/javaee/7/api/javax/mail/package-summary.html[`JavaMail`] library. This feature is composed of three commands: `checkemail`, `setemail` and `remind`.

* `checkemail` command: display the email address that the user has set to send emails from. The app will censor the email address.
[NOTE]
If user has not set an email, the email address will be an invalid email and the app show a "You have not set your email yet!" message.

* `setemail` command: set the email address used for sending reminders to the customers.
[NOTE]
Only gmail is accepted by the app.

* `remind` command: automatically generate an email containing some core information about the loan, and send it to the corresponding customer from user's email. This command will use the `JavaMail` library.
[NOTE]
The email will contain the `Name`, `BikeId`, `LoanStartTime` and `LoanRate` of the loan.

Given below is an example usage scenario and how the reminder email mechanism behaves at each step.

*Step 1.* The user launches the application for the first time. The user's email address is invalid by default.

*Step 2.* The user executes `checkemail`. The following sequence diagram shows how `checkemail` works:

image::CheckEmailSequenceDiagram.png[]

The command executes `Model#getMyEmail()`, which calls `UserPrefs#getDefaultEmail()` and returns user's email stored in `UserPref`. The app checks if user's email equals to `"default"`. In this case, they are equal, so it throws a `CommandException`.

*Step 3.* The user executes `setemail e/EMAIL x/PASSWORDFORAPP`. This command does a few checks first:

.. The app then checks if `EMAIL` equals to the user email that has been already set to the app. If so, then a `CommandException` is thrown, to warn the user that they are setting the same email as last time.

.. Otherwise, `SetEmailCommand#isValidGmail(EMAIL)` is called to check if `EMAIL` is a valid gmail. If not, a `CommandException` is thrown to warn the user that they are setting invalid email address.

*Step 4.* The user forgets what email has been set before, so the user executes `checkemail` again. The procedure is the same as in *Step 2*. However, the app detects that user's email is not the default invalid string this time, so it creates an `Email(userEmail)` object and executes `Email#getCensored()`. Then, the function returns a `CommandResult` with a success message and the censored user email.

*Step 5.* The user sends a reminder email to a customer by executing `remind pw/EMAILPASSWORD id/LOAN_ID`. This command implements the following operations:

a. Execute `Model#getLoanById()` and return an optional<Loan> object called `targetLoan`.

b. Check if `targetLoan.isPresent()` returns a non-null `loan`, then check if its `LoanStatus` is `ONGOING`.

c. If its `LoanStatus` is `ONGOING`, create a `SendReminder(model, EMAILPASSWORD, loan)` object and execute `SendReminder#send()` to send email. +
The `SendReminder#send()` method calls `SendReminder#createReminderEmail(session, userEmail)` to create the content of the email, connects user's email using `EMAILPASSWORD` and finally send the email.
[NOTE]
For Steps (b), if the next step cannot be executed, a `CommandException` with corresponding failure message will be thrown.
[NOTE]
If it throws a `CommandException` with authentication failed message in step (c), please check if user's email and password are correct. If they are, please make sure that the `Less secure apps` setting of user's email is enabled. If it is not, enable it and refresh the page.

==== Design considerations
*Aspect: use user's personal email vs share an immutable common email*

* *Alternative 1 (current choice):* Use a user-specified email.

** Pros:
*** The user has a choice of what email address to use.
*** The user needs to type in the correct password if they want to send a reminder email, which ensures the security and privacy of the email.

** Cons:
*** The user needs to enable the `Less secure apps` setting, which could be a security concern.

* *Alternative 2:* Use a common email provided by the app.

** Pros:
*** The user does not need to set their own email when sending reminder emails, reducing hassle when setting up.
*** The user does not need to type in a password when sending a reminder email.

** Cons:
*** The common email is less secure, as its password can be found within the program.
*** The password of the common email can be changed by malicious users.
*** The email might get overloaded.
*** Customers might receive spam emails, as the `remind` command does not require a password.

include::../DeveloperGuide.adoc[tag=hideinfo]
==== Future considerations
We plan to add a feature that can automatically send an e-receipt to the customer after `return` ing a loan.

include::../DeveloperGuide.adoc[tag=sendemail]
The e-receipt will contain the `Name`, `BikeID`, `LoanStartTime`, `LoanEndTime` and `TotalCost` of the loan.

0 comments on commit 93821c8

Please sign in to comment.