tp

Developer Guide


Acknowledgements

AddressBook Template

The format of this Developer’s guide (DG) as well as some basic support is inspired/ taken from the AddressBook project’s DG.

Bitwarden

The idea for this product stems out from Applications like Bitwarden and the like that serve to store and protect users passwords. Many of our features were inspired by these applications.

CLI Applications

The idea for this product is for users who are familiar with CLI environments. Users are able to see only the necessary information given in text format. Things can be done faster with just a single line of input command compared to navigating through a GUI environment.

Back to Table of Contents

Setting up, getting started

Setting up the project in your computer

First, fork this repo, and clone the fork into your computer.

If you plan to use Intellij IDEA (highly recommended):

  1. Configure the JDK: Follow the guide [se-edu/guides] IDEA: Configuring the JDK to ensure Intellij is configured to use JDK 11.
  2. Import the project as a Gradle project: Follow the guide [se-edu/guides] IDEA: Importing a Gradle project to import the project into IDEA.

Note: Importing a Gradle project is slightly different from importing a normal Java project.

  1. Verify the setup:
    1. Run the seedu.securenus.SecureNUS and try a few commands.
    2. Run the tests to ensure they all pass.

Before writing code

  1. Configure the coding style If using IDEA, follow the guide [se-edu/guides] IDEA: Configuring the code style to set up IDEA’s coding style to match ours.

Tip: Optionally, you can follow the guide [se-edu/guides] Using Checkstyle to find how to use the CheckStyle within IDEA e.g., to report problems as you write code.

  1. Set up CI This project comes with a GitHub Actions config files (in .github/workflows folder). When GitHub detects those files, it will run the CI for your project automatically at each push to the master branch or to any PR. No set up required.
  2. Learn the design When you are ready to start coding, we recommend that you get some sense of the overall design by reading about Our Architecture.
Back to Table of Contents

Design

Legend

The class diagram visibility / access modifier is represented by the table below

Architecture

This Architecture Diagram explains the high-level design of the App. Given below is the quick overview of main components and how they interact with each other.

Main Components of the architecture

SecureNUS has 1 class called SecureNUS. It is responsible for,

SecretStorage is responsible for the management of Secret Objects which store information of different Secret classes, e.g. passwords, credit cards. It also manages the different underlying data structures within it that help optimize the speed of queries through indexing, etc. It consists of 3 classes: SecretMaster, SecretSearcher and SecretEnumerator, which contain the different views.

UI is the main interface the user has access to through the Command Line with the application. All the information inputs are received by the UI. It also determines what action to make, such as in altering the data in the storage or providing some form of information (e.g. their secrets) to the user. These actions are defined by Command classes in the SecureNUS component to be executed. The UI Component also determines how responses are being formatted to the users for better readability and understandability.

Backend handles the details regarding the initialisation (importing) and saving (exporting) of data across sessions. At initialisation, it will be used by SecureNUS component to set up the SecretStorage by decrypting the database output files from previous sessions. It deals with the encryption and export of the data during the termination of the app.

Logger is the main component used for logging of issues and logging of states that arise in the execution of the application. It is used to allow developers to have a better understanding of why certain functions may fail, provide an unexpected outcome or experience an unexpected action. In the event of a failure when used by users, the logs store the state of the application reached by the user to serve as a form of bug report that users may submit as an issue to be solved by developers, in the case of an unexpected issue. The Logger component also deals with the formatting of issues in a way that can be read by developers.

The following diagram shows how the classes are segregated based on the provided high level architecture. Each cuboid here represents a class:

Here, each cuboid represents a class. The Logger component is extracted from the Application Component to represent that every part of the application is directly connected to the Logger. For the sake of better viewability, the Logger component will be excluded for better viewability and clarity of the diagram, since it is intricately interwoven in every class, across many methods.

Back to Table of Contents

How the architecture components interact with each other

The Sequence Diagram below shows how the components interact with each other for the scenario where the user creates a new basic password initiated using the command new password. Some details are omitted for the sake of better viewability in demonstration. Details after the loop are removed as well.

In the diagram above, the following Components-Classes are:

The SecureNUS Component runs the loop that awaits a response from the user. This command new password is being handled by the UI

Back to Table of Contents

SecureNUS Component

Class Diagram of SecureNUS Component

The above diagram shows how the SecureNUS component works.

SecureNUS is the main driver of this java application. All of the user inputs will go through the UI component then parsed through the Parser class, which creates one of the predefined Command objects. The command defined by the Command object is then executed by the SecureNUS object which grants the Command objects access to read or write data from the SecretStorage Component.

Command

The API of this component is specified in the package command. Command is an abstract class that is inherited by various components such as AddBasicPasswordCommand.java

The diagram above shows a simple example of how the command is created before being executed by the SecureNUS. Not all classes are shown here for simplicity. The Command consists of the Command abstract class that handles all of its command constructors and executions through its child classes. Sequentially, the user inputs a command in Ui, that is parsed in Parser, which then instantiates a Command object, which is then executed by SecureNUS object.

SecretStorage Component

The API of this component is specified in the package storage. The diagram below features the high-level understanding of how this component works. Each rectangle represents a class, while the SecureNUS and Backend nodes represent components.

The SecretStorage component abstracts the data that is to be stored into many views/ indexes. This optimizes the speed of queries for many types of queries without developers needing to access the individual data structures used. The data structures, namely Hash Table and Array are stored in the SecretSearcher and SecretEnumerator class respectively. This allows for optimised queries for different operations, namely getting the secrets by name and index (within or without folders) at O(1) time. During the initialisation of the application, the Backend will import past data to the SecretMaster. During saving/ termination of the application, the SecretMaster class will export the data stored in SecretEnumerator (the one with the ArrayList View) and Backend will handle encrypting and saving it into an external file.

The following class diagrams show how these work in the code.

Class Diagram of SecretStorage Component

Class Diagram of SecretStorage Component without methods


Backend Component

The API of this component is specified in the class Backend.java. In this diagram, rectangles and cuboids represent classes.

The backend manages the saving and loading of data from the database.txt file. To do so, it collates and organizes information stored in the SecretMaster and encrypts it into the database.txt. When starting up, it will decrypt the database.txt file and transfer its data into the SecretMaster.

The following class diagram shows how these work in the code. Details of the secrets and storage packages which are in the other components are removed for better viewability.

Class Diagram of Backend Component

Back to Table of Contents

UI Component

The API of this component is specified in Ui The following diagram shows a high level understanding of how the UI Component works. The rectangles represent classes while the cuboids represent Components.

The UI consists of the Ui class which handles all the inputs provided by the user. The Ui then sends information to the parser which will interpret the commands provided by user input. The Parser will create Commands which will be sent to SecureNUS to execute some command that will alter the data in SecretStorage. The Ui also handles responses/ feedback to the User.

Class Diagram for UI Component

Back to Table of Contents

Implementation

This section describes some noteworthy details on how certain features are implemented. This developer guide will show an example of 3 implementations, namely, Add Basic Password Feature, Delete Password Feature, and List Password Feature

Add Basic Password

The new function allows the user to add new basic password stored in the password manager. When the user selects the add basic password function, they will be prompted to enter the name, url, username, and password. Once the users enters the prompt, a new password will be created

The basic password, an object that extends the secret object, has a mechanism that is facilitated by SecureNUS’s parse() and execute() command. It is then stored internally in ArrayList in SecretStorage, and is saved to database.txt by the Backend class.

Basic Password has attributes: name, folder name, username, password and url.

To instantiate a basic password object, parse command creates a constructor of BasicPassword that extends Secret. The class prompts the user to input these additional attributes.

AddBasicPasswordCommand extends AddSecret abstract class and extends Command class. The Add Basic Password feature will implement the following operations:

Given below is an example usage scenario and how instantiation of basic password behaves at each step. Some details are omitted for the sake of better viewability in demonstration. Details after the loop are removed as well. The usage scenario is not an object diagram, a sequence diagram, nor a class diagram. It is purely to demonstrate the feature usage.

Step 1. The user launches the application for the first time. The SecureNUS will be initialized. The user will interact directly with SecureNUS Class.

Step 2. When the user executes “new basic_password” command to add basic password, the SecureNUS calls parse() method to parse the user’s input

Step 3. AddBasicPasswordCommand is then instantiated by the Parser by calling its constructor.

Step 4. The parser then would return back to the SecureNUS class, which will then call the execute method in the AddBasicPasswordCommand object. The method will return false in this case because it is not an exit command

Step 5. In the AddBasicPasswordCommand execute method, it will instantiate a new BasicPassword Secret object.

Step 6. The BasicPassword object will then be written to the SecretMaster that stores all of the password locally

Step 7. Finally, when saving, the data in the SecretMaster is then written to the harddisk by the Backend.

The complete sequence diagram is given below

Sequence Diagram of Add Basic Password

Back to Table of Contents

Delete a Password

The delete function allows the user to delete a stored password from the password manager. When the user selects the “delete” function, they will be prompted to enter the name of the password they want to delete. Once the user enters the name, the app will delete the password from SecretMaster if it exists.

Delete Password has attribute: name

To instantiate a DeleteCommand object, parse command creates a constructor of DeleteCommand that extends Command.

The Delete feature will implement the following operations:

Given below is an example usage scenario and how instantiation of basic password behaves at each step. Some details are omitted for the sake of better viewability in demonstration. Details after the loop are removed as well. The usage scenario is not an object diagram, sequence diagram, nor a class diagram. It is purely to demonstrate the feature usage.

Step 1. The user launches the application for the first time. The SecureNUS will be initialized. The user will interact directly with SecureNUS Class.

Step 2. When the user executes “delete basic_password” command to delete basic password, the SecureNUS calls parse() method to parse the user’s input

Step 3. DeleteCommand is then instantiated by the Parser by calling its constructor.

Step 4. The parser then would return back to the SecureNUS, which will then call the execute method in the DeleteCommand object. The method will return false in this case because it is not an exit command

Step 5. In the DeleteCommand execute method, it will delete the corresponding Secret object in the SecretMaster.

Step 6. Finally when saving, the updated data in the SecretMaster is then written to the harddisk by the Backend.

The complete sequence diagram is given below.

Sequence Diagram of Delete Command

Back to Table of Contents

List all Secrets

The list function allows the user to view all the passwords stored in the password manager along with their descriptions. When the user selects the list function, the app will display all the stored passwords and their descriptions in a table format. The table will include columns for the name of the password, its description, and the date it was added to the password manager.

List has attributes: folder name

To instantiate a basic password object, parse command creates a constructor of ListCommand that has attribute folderName.

The List feature will implement the following operations:

Given below is an example usage scenario and how instantiation of basic password behaves at each step. Some details are omitted for the sake of better viewability in demonstration. Details after the loop are removed as well. The usage scenario is not an object diagram, sequence diagram, nor a class diagram. It is purely to demonstrate the feature usage.

Step 1. The user launches the application for the first time. The SecureNUS will be initialized. The user will interact directly with SecureNUS Class.

Step 2. When the user executes “list folderName” command to list all passwords in folder folderName, the SecureNUS calls parse() method to parse the user’s input

Step 3. ListCommand is then instantiated by the Parser by calling its constructor.

Step 4. The parser then would return back to the SecureNUS, which will then call the execute method in the ListCommand object. The method will return false in this case because it is not an exit command

Step 5. In the ListCommand execute method, listSecrets will access the secrets from the SecretMaster.

Step 6. In the ListCommand execute method, getSecretTypeInfo will return the corresponding secret’s information (Name, username, url, password) from the SecretMaster.

Step 7. Finally, it will output using system.out to the terminal.

The complete sequence diagram is given below.

This simplified sequence diagram shows what happens when a user lists all passwords in a folder called folderName:

Sequence Diagram of List Command

Back to Table of Contents

Appendix: Requirements

Product Scope

Target user profile:

Value proposition:

Back to Table of Contents

User Stories

Priority

As a …

I want to …

So that I can …

***

user

view all my passwords in a single location

have an overview of all my stored passwords

***

user

find my passwords in an intuitive and structured manner

easily retrieve a password

***

user

Store different types of passwords

easily retrieve passwords with multiple hidden fields like a Credit Card.

***

user

view all my stored passwords at a glance (without details)

quickly see what passwords I have used before

***

user

delete stored passwords

remove passwords that I no longer use

***

user

save my passwords across different sessions

Keep my passwords across different sessions without the need to constantly retype or keep the application online to ensure the storage is not cleared.

***

user

use local storage to store my passwords

have my passwords stored locally so that they are safer from online breaches

***

user

encrypt my passwords when saving in the file

ensure that nobody but me has access to the .txt file that stores my passwords

**

user

cancel a password addition when i mistype something wrong

Use less commands to rectify my mistake made

**

user

authenticate myself before accessing

ensure that nobody else but me gets access to my stored passwords

**

user

know when I created a certain password

keep track of how long my passwords have been used for

**

user

not have to think of a strong password by myself and let the app handle it

know when to change my password as passwords should be changed periodically

**

user

search/filter out specific passwords

quickly refer to a password that is used for a specific login (e.g. password for NUS email)

**

user

copy and paste my passwords

not have the password revealed on my terminal, simply paste from clipboard

*

user

hide my password while typing it

not allow people around me to view my password as I type

*

first-time user

want to be able to see the demo to use the password manager

learn how to use SecureNUS

*

user

receive notification any of my previous passwords are reused

use a new and different password each time

*

user

receive reminder to change passwords that have not been changed for an extended period of time

not have to check every single password manually (but still have the ability to) to know when to change my passwords

*

user

select a particular stored password and expand it to reveal details

use the details of the password to make decisions regarding the password (e.g. change the password if it has been used for a long time, create a stronger password the next time if the current one is not strong, etc.)

*

user who wishes to use complex passwords

generate complex passwords for me

not have to think of a strong password by myself and let the app handle it

*

user

sync my stored passwords manually

have my stored passwords on different devices

Back to Table of Contents

Non-Functional Requirements

Back to Table of Contents

Glossary

Back to Table of Contents

Appendix: Instructions for manual testing

Launch and shutdown

  1. Initial launch
    1. Download the jar file and copy it into an empty folder.
    2. Open a command window (If you are on Windows, use the DOS prompt or the PowerShell).
    3. Run the java -version command to ensure you are using Java 11.
    4. Launch the jar file using the java -jar command rather than double-clicking (reason: to ensure the jar file is using the same java version that you verified above). Use double-clicking as a last resort.
  2. Shutdown
    1. Enter the exit command Expected: Exits the program gracefully. All data is saved.

Saving data

The following directory and file will be created upon initial launch of SecureNUS:

assets/database.txt

Stored passwords are saved after exiting the program gracefully.

  1. Missing directory
    1. Simulate by deleting the assets folder
    2. Expected: A new folder will be created upon the next launch of the program, with an empty database.txt file inside
  2. Missing data file
    1. Simulate by deleting the database.txt file in the assets folder
    2. Expected: An empty database.txt file will be created in the ‘assets’ folder upon the next launch of the program
  3. Data not saved
    1. Simulate by forcefully exiting the program (i.e. exit without entering the exit command)
    2. Expected: All unsaved data is lost
  1. menu Expected: Displays menu.

Adding a password

  1. new myBasicPassword1 Expected: Input fields are displayed and user keys in the relevant details. The basic password is then stored successfully.
  2. new myBasicPassword2 f/myFolder Expected: Same as previous, but this basic password is filed under myFolder folder
  3. Incorrect format like new, new o/, new o/InvalidPasswordType Expected: Error message displayed.

Listing all passwords

  1. list Expected: Lists myBasicPassword1, myBasicPassword2 and myNUSNetPassword and their details
  2. list f/myFolder
  3. Expected: Lists myNUSNetPassword only Incorrect format like list f/nonExistentFolder Expected: Error message displayed.

Search for password

  1. search my Expected: Displays three passwords with names containing “my”

View password

  1. view myBasicPassword1 Expected: Displays password and details of myBasicPassword1
  2. Incorrect format like view, view nonExistentPassword Expected: Error message displayed.

Edit password

  1. edit myBasicPassword1 Expected: Input field displayed for user to enter new password for myBasicPassword1
  2. Incorrect format like edit, edit nonExistentPassword Expected: Error message displayed.

Delete password

  1. delete myBasicPassword1 Expected: myBasicPassword1 is removed from storage.
  2. Incorrect format like delete, delete nonExistentPassword Expected: Error message displayed.
Back to Table of Contents