Tuesday, October 9, 2018

Adding an Event to the Google Calendar using OAuth

In this post, I will illuminate how to add an event to the Google Calendar using OAuth. If you want to know about how OAuth basically works, you can visit my previous post on Open Authorization (OAuth 2.0), where I explained how it works by protecting the user resources while it enables other applications to access certain protected resources on behalf of the user, given that the user has granted permission for access preceding it.

Registering your Application and Enabling OAuth 2.0 Access in Google API Console

   1. Let's start by registering our application which requests the Google Calendar permissions, by visiting the Google API Console.

   2. You will get a Dashboard similar to the one in the picture below. Click on the Highlighted Dropdown. If you have not made any projects yet, your dropdown button is the one with 'Select a project' on it.



   3. After you click on the dropdown, you will get a modal as the one below. As you can see, this modal shows all the Projects you have currently made, and in the picture below, you could also see the Project: 'Event Creation Application' which I have made initially when developing this application. To register the application, we must create a project first, so click on the 'New Project' button I have highlighted.



   4. After that, you will land on a page which looks like the one below, where you have to enter your Project Name, and then press the 'Create' button.


   5. You will receive the success notification below on your Google Console Dashboard once the project has been successfully created.


   6. Now, having created the project, let's proceed with enabling of OAuth 2.0 API access. For this you need to go to the Google API Console Credentials page. Before going ahead, make sure you have selected the correct project in the project dropdown. Click on 'Create credentials' button, and select 'OAuth client ID' option from the context menu.


   7. You will get a page to fill the Application details which looks not exactly, but somewhat similar to this:


Please fill in all the necessary details. Make sure you give a meaningful Name for the Application as this is what will be displayed in the user consent page, and users may feel uneasy to grant access if it is not a proper name. You must also make sure to give the Redirect URI of your application as this is the endpoint to which the Authorization Server will send responses to.

    8. Also make sure to select Web Application under the Application type.

   9. After you have created the credentials, you will be provided with a Client ID and Client Secret. Please note them down.

How to create an Application that adds Events to Google Calendar

You can visit this GitHub link if you would like to view and try out the sample application I made using Spring Boot to add events to the Google Calendar.

If you are trying this application out, there are some changes you need to make to the code. I have indicated all these changes with the 'CHANGE:' tag below.

This application will only contain one front end page, which is the one below:


   index.html:




CHANGE: In index.html, you may change the client id to your one in the JavaScript method, redirectToGoogleOAuthEndpoint().

   1. You can press the 'Grant Access to Google Calendar' button to grant access to your calendar. You will be redirected to a Login page or Choose an Account page upon clicking like the one below. As you can see, the Application Name shown in the Sign in will be the name you gave when registering the application by creating the Credentials.


   2. After you have granted access, you will be redirected to the first and the only page of the application, while in the background, the Authorization Server will return a response containing the Authorization Code when the user grants access.

As you can see in the code above, once 'Grant Access to Google Calendar' button is pressed, redirectToGoogleOAuthEndpoint() method is called where the required query parameters are set, and the full, final Authorization Endpoint URL to be redirected to is built, finally, redirecting user to the Authorization Endpoint after everything is set.

Authorization Endpoint of Googlehttps://accounts.google.com/o/oauth2/v2/auth

Authorization Request Parameters:
  • client_id            (Required)
  • redirect_uri       (Required)
  • scope                 (Required)
  • access_type       (Recommended)
  • state                   (Recommended)
  • response_type   (Optional)
  • include_granted_scopes, login_hint, prompt     (Optional)
I have used all the required and recommended parameters with the optional response_type parameter set as 'code' which is the value normally sent in the Authorization requests in Authorization Code Grant Type, but you can add any optional ones too if you want to.

Scope for Google Calendar Accesshttps://www.googleapis.com/auth/calendar

State, which is a random string is used to prevent CSRF as I mentioned in my previous post.

   application.properties:


CHANGE: You may change the client_id, and client_secret values to the values you obtained when you created the credentials in Google API Console.

   EventController.java:





   3. As I mentioned above, when user grants access, the Authorization Server will send the response to the Redirect URI which is http://localhost:8081/callback in this case. Once the endpoint that maps that URI is triggered by the Authorization Server response, we can retrieve the value of the parameter 'code' sent in the response which is the Authorization Code, and make a new POST request to the Authorization Server, requesting an Access Token in exchange for the Authorization Code.

Token Endpoint of Googlehttps://www.googleapis.com/oauth2/v4/token

Access Token Request Parameters:
  • code
  • client_id
  • client_secret
  • redirect_uri
  • grant_type
All the parameters mentioned above are required.

grant_typeauthorization_code

Please note that the redirect_uri added here must be the same redirect_uri used in the initial authorization request before.

Another thing to note is that the Content-Type must be application/x-www-form-urlencoded.

After setting the parameters, we can send the POST request, and obtain the JSON response, from which we can retrieve the 'access_token' parameter value sent by the Authorization Server, and save it in a variable for future use when accessing resources.

After receiving the Access Token, user is redirected to index.html as I stated above.

   4. Now you can fill the form, and click the 'Submit' button. Clicking this button will trigger the JavaScript method: addEventToGoogleCalendar() which will take the provided form details, and make an AJAX POST call to the '/addEvent' Endpoint URI of the server which handles the event addition to the Google Calendar. 

   5. When the '/addEvent' endpoint is triggered, a POST request will be made to the Google Calendar API Resource Server to add the event to the Calendar, and the JSON response sent by the server will be read finally when returning the success response to the frontend in JSON format, adding the link of the created Event to it.

It is noticeable that I have only made the Email, Start Date and Time, and End Date and Time fields required in my form as they are the minimal set of values that must be present to add an event to the Google Calendar. 

Email is the calendarId which is the calendar identifier, and without setting this, it is also possible to place 'primary' as the value, and the primary calendar of the logged in access granted user will be used.

Summary, Location, Description, and Attendees are some of the other optional parameters that can be given when making a Calendar Event. The Event ID is also an optional parameter, which if not provided, will be generated by the server for you. In this case, I have made use of some of these optional parameters.

Google Calendar Endpoint
https://www.googleapis.com/calendar/v3/calendars/calendarId/events

Another thing to note is that the Content-Type is application/json. Therefore, all the above mentioned parameters are added to JSON object before making it a string finally, read to be sent.

As we have the Access Token now, when communicating with the Resource Server, we must send it, and this is done by adding it in the Header of the request as "Authorization" being: "Bearer XXX" where XXX is the value of the Access Token.

Please note that the models for Job and Response which maps an Event and a Response to frontend respectively are made as well in the models folder.

   6. Depending on whether the Event Addition to Google Calendar is successful or not, a message will be given to the user. If the event addition is successful, the message below will be displayed, and the user will be able to view the added event in the Google Calendar upon clicking the 'OK' button.

   Success Message:


   Event added to the Google Calendar:


References

Open Authorization (OAuth 2.0)

Open Authorization (OAuth) is an open-standard framework for delegated authorization. OAuth provides the capability for applications to access the protected data or resources of a user of a third-party application, without exposing or having the need to provide login credentials of that application to the party that needs to access the data.

When an application wants to access third-party resources on behalf of the user, instead of requesting the username and password for the third-party application from the user, OAuth framework is used now to obtain an access token which grants access and permission to a predefined set of resources. Using OAuth secures the user resources, as otherwise, login credentials may have to be provided, and providing login credentials to another application gives the application the ability to perform any action as the user. For example, if the application needs to access only the email contacts, but users have to provide the login credentials for the application to access the contacts, the application will have the capability to perform actions like sending emails to people pretending to be the real user, and perform actions for which the user may not have originally intended to give permission.

How OAuth Works

The picture below illustrates how OAuth works using Authorization Code Grant Type (other grant types also have a similar flow with slight differences):


Roles

  • Client - This is the resource requester; the application which requests resources on the user's behalf.
  • Authorization Server - This is the third-party application that issues the access tokens for accessing its resources.
  • Resource Server - This also belongs to the third-party application which contains the resources that needs to be requested. 
  • Resource Owner - This is the user; the owner of the protected resources. 


Protocol Endpoints

Both the Authorization Endpoint and the Token Endpoint are located in the Authorization Server while the Redirection Endpoint (Redirect URI in the diagram above) is located at the Client application.
  • Authorization Endpoint - This is used to get the user's approval/authorization to issue an access token to access the protected resources.
  • Redirection Endpoint - This is the endpoint to which the Authorization Server sends responses to in the client application, after receiving and processing the requests made on the Authorization Endpoint and the Token Endpoint.
  • Token Endpoint - This endpoint issues the access tokens.


The following are some of the important points that must be noted regarding OAuth:
  • Both the Authorization Code and the Access Token have a validity period which means that it will expire after a certain time period decided by the Authorization Server.
  • Authorization Code can be seen in the browser request, but others like the Access Token cannot be seen as the communication which takes place after user access consent is server-to-server communication.
  • The Client application must be registered with the third-party application which contains the resources, so that it can identify the client who requests the resources. Upon registering the application, you will receive the Client Id (Consumer Key/Client Key/App Id) which is the username of the application, and the Client Secret (Consumer Secret/App Secret) which is the password of the application requesting the information. 
  • Client Id of the registered application must be sent to the Authorization Server when requesting both Authorization and Access Token.
  • Scope refers to the permissions that needs to be requested.
  • Multiple permissions can be requested at the same time using Scope.
  • State is a random string which is used to prevent CSRF, and is therefore recommended. It is sent to the Authorization Server, and the server sends it back to the client in response. 
  • Resource Server defines which resources can be accessed and using which scopes.
  • Client Secret must be sent to the Authorization Server when requesting an Access Token as the server has to validate the requester. The initial request does not need to have the Client Secret sent to the server.
  • The user has to give the consent only once.


Grant Types

There are several ways in which Access Tokens can be obtained, and these mechanisms are called Grant Types.
  1. Authorization Code Grant Type - This is used to develop Server-side Web Applications.
  2. Implicit Grant Type - This is used in implementing Client-side Applications like Single-page JavaScript applications. It has no Token Endpoint as initial response itself returns a Token.
  3. Resource Owner Password Credentials - This is used in Trusted Apps like Facebook Mobile App where username and password is requested, and is possible to provide the login credentials without any worries. It has only the Token Endpoint, and does not have an Authorization Endpoint.
  4. Client Credentials - This is used in Server-to-server communication, and it has no user involved. There are times when although no user is involved, information must be exposed securely to outsiders or other applications. For instance, this can be used when retrieving data like Weather data or Traffic data from an API. It has only the Token Endpoint, and does not have an Authorization Endpoint.


Some Use Cases

  • Logging on to websites using other social websites like Facebook, LinkedIn, Twitter, etc. 
  • Automating the uploading of some files to Google Drive.
  • Retrieve data from Facebook and display it or carry out some processing. For example, this is done by the fun applications that access information and predicts things like "What your profile picture reveals about you?" or "When will you die?"
  • Accessing Gmail contacts.
  • Access Photos stored on another site.
  • Updating Gaming Scores and storing them on another site.


One of the advantages of using Social Websites to login to other websites is that you do not need to create multiple accounts, but at the same time, one of the disadvantages is that it can become a single point of failure because if the credentials to the social website are leaked, then others can have access to all the other websites you logged into using the social login.

While OAuth protects the users' resources, one of the disadvantages of OAuth is that whoever bearing the Access Token can access the data, which means if an attacker gets or steals this Access Token, they can get the permission-given data until the Access Token expires. 

Thursday, October 4, 2018

Double Submit Cookies Pattern

As I mentioned in my previous posts, Double Submit Cookies Pattern is another mechanism of preventing CSRF attacks.

Similar to the Synchronized Token Pattern, a random string token is generated whenever a user logs in and a session starts in Double Submit Cookies as well. One of the main differences is that the server only generates the token, and does not store it in the database in Double Submit Cookies Pattern, whereas the token is stored in the database in Synchronized Token Pattern.

What happens here is after generating the CSRF token, the server sets a cookie which contains the CSRF token in the client's browser. 

If we take the same example as in the Synchronized Token Pattern, where an admin fills a form to create a user account, in a similar fashion, in Double Submit Cookies Pattern too, a hidden field which contains the CSRF token must be embedded in the form. The CSRF token value to be embedded is not retrieved from the server side through an AJAX call like in Synchronized Token Pattern. In Double Submit Cookies Pattern, we retrieve the CSRF token value from the CSRF cookie stored in the browser using Javascript.

To read cookies through Javascript, the domain should match with the current domain which means only the cookies of the current domain will be visible. CSRF cookie cannot be protected by httpOnly flag that is used to prevent any client side Javascripts from reading and accessing this cookie because the requirement of the problem needs the reading of the CSRF token using Javascript.

When the request is sent to the server, either the body will contain the CSRF token embedded in the form or the header, and since the browser selects and sends all the cookies that fall under the current domain and path to the server along with all the requests to maintain the session, the server can easily validate whether the current session is valid or not by reading the received CSRF token cookie value and comparing it against the received CSRF form-embedded token value.

Therefore, this makes it impossible for attackers to obtain and access the cookies for another domain, and attackers' request body/header will not have this token.

The diagram below illustrates the flow of the Double Submit Cookies Pattern process mentioned above:



We do not protect GET requests against CSRF attacks, as we expect client to send the CSRF token, and the token cannot be sent in the query parameters of a GET request as it exposes the token.

You can visit this GitHub link to view the sample implementation of Double Submit Cookies Pattern to prevent CSRF. I have hard-coded the username and password for demonstration purpose.

Username and Password both: ssd

As in the diagram above:


   1. User logs in to the system using index.html. The form action points to login.php, and the form details will be submitted to it when the user clicks the Login button.

   Login Page:

   index.html:







   
   
   2. If the user has provided the correct login credentials, the user is redirected to add_user.html.

   login.php:
























As in Synchronized Token Pattern, for each login, a new session is made for the user, and it is ensured that a new PHP Session Id is generated for each login after invalidating the already existing session.


Similar to the approach taken in Synchronized Token Pattern, the CSRF Token, being a randomly generated string, in this case, has been produced by hashing and Base64 encoding the random integer created while taking the current timestamp into account, through the line:
$csrfToken = base64_encode(hash("sha256", uniqid(mt_rand(1000, 9999)
.microtime(), true), true));

Afterwards, setcookie() function in PHP has been used to create and store a cookie which contains the generated CSRF Token value in the user's browser, through the line:
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/");
Cookies normally contain the five key-value pairs: Cookie Name, Cookie Value, Domain, Path, and Expiry Date. As it can be seen the Name of the Cookie is set to be "CSRF_TOKEN", Value is the generated CSRF Token value, and Path is "/" (root) which means all the paths of the particular domain to which the cookie belongs. The Cookie is set to expire after 30 days. The domain is not mandatory to be added to the setcookie() function along with the other required and appropriately added details as the browser automatically sets it as the current domain as it is the domain setting the cookie in the browser at that point of time.  

   3. The CSRF Token for the session is retrieved from the CSRF_TOKEN cookie stored in the user's browser using JavaScript, and when the user fills the form and clicks the Insert button, the form details are submitted to the pointed validate_token.php.

   Add User Page:

   add_user.html:


























When the form has completely loaded as checked by the document.readyState if statement, the CSRF token value is retrieved from the cookie stored in the user's browser by calling getCSRFToken() method, passing the Cookie Name as a parameter, and after retrieving the CSRF token value, a new hidden input field is added to the form, and this input field contains the retrieved CSRF token which is to be passed to the server-side in the attempt in enabling the server to recognize whether the request is legitimate or not.

getCSRFToken() method works by accessing cookies of the current domain using document.cookie, decoding the retrieved value which contains all the cookies for the current domain, and splitting by the delimiter ";" to separate key-value pair cookies of the retrieved cookie set. Then, in a loop, each key-value pair is accessed and the white spaces in the beginning are removed, if found, and afterwards, if it is possible to find the correct key-value pair which contains the string: "CSRF_TOKEN=" and the CSRF Token value, the CSRF Token value which is the value in the key-value pair is extracted and returned. 

   4. When the form details are submitted to validate_token.php on Insert button click, the CSRF Token values will be compared and validated, and a message will be returned based on the outcome of the comparison.

   validate_token.php:































validate_token.php checks whether the request is POST and checks to see whether the PHPSESSID which is the PHP Session Id has been set. Additionally, it checks to see whether a value has been set as the 'csrf_token' in the request body and also in the CSRF_TOKEN cookie, and if it has been set, the CSRF Token value stored in the received CSRF Token Cookie is compared with the value sent in the POST request body to see whether the values are equal and the request is legitimate. Either a successful message as in the picture included below, or an error message will be displayed in the client-side based on the equality comparison outcome.

This way we do not need to store a whole set of CSRF Tokens mapped against each user's each session in the database.

Wednesday, October 3, 2018

Synchronized Token Pattern

Synchronized Token Pattern is one mechanism to prevent or handle the security attack: Cross-Site Request Forgery (CSRF). My previous post on CSRF will give you an idea about what CSRF is.

Each time a user logs in, a new session is created for the user if the site allows multiple logins like Facebook, allowing users to log in from many browsers and devices. In Synchronized Token Pattern, a random string token is generated in the server side whenever a user logs in and a new session is created. This token is stored in the database mapped to each session of the user. The server then exposes a URL which can be accessed by the user to get the generated CSRF token.

Lets assume that the user is an Administrator making a user account for another user of the system. The admin will fill the form providing the relevant details of the user and submit it. The server will receive all the form details through the request made to the backend. 

After obtaining the token, the user can embed the token in a hidden field in the form and send the token in the request along with the user details to the server when posting data. This way, the server can identify whether the request is valid as only a valid request will contain the Session Id, Username, and CSRF token that matches the values stored in the database.

The user must make an AJAX call to obtain this CSRF token. The attacker will not be able to obtain this token, as whenever a browser makes an AJAX call, it validates the current domain against the request domain. If the call is made to www.abc.com, this domain should match in the browser and the server call. The browser will only send the request if the domain matches. By default, making Cross-domain AJAX calls is not possible as it is blocked. It can be enabled if needed, but for these security reasons we do not enable it normally.

As attacker will not be able to obtain the CSRF token using an AJAX call as domains will not match, CSRF will not be possible as attacker's form will not contain the CSRF token, making the request invalid even if all the other details match.

The diagram below illustrates the flow of the Synchronized Token Pattern process mentioned above:



You can visit this GitHub link to view the sample implementation of Synchronized Token Pattern to prevent CSRF. In this example, instead of using a real database, the CSRF token generated for each session is mapped to a PHP key-value associative array in the Server-side, and is used in validating the requests. I have also hard-coded the username and password for demonstration purpose.

Username and Password both: ssd

As in the diagram above:


   1. User logs in to the system using index.html. The form action points to login.php, and the form details will be submitted to it when the user clicks the Login button.

   Login Page:

   index.html:






 

   2. If the user has provided the correct login credentials, the user is redirected to add_user.html.

   login.php:




For each login, a new session is made for the user as mentioned earlier, and it is ensured that a new PHP Session Id is generated for each login after invalidating the already existing session.

A CSRF Token is also generated for each user login session, and for demonstration purpose, as mentioned previously, it is stored in a PHP associative array, mapped against the Session Id through the line:
$csrfTokenArray[session_id()] = $csrfToken;

The CSRF Token, being a randomly generated string, in this case, has been produced by hashing and Base64 encoding the random integer created while taking the current timestamp into account, through the line:
$csrfToken = base64_encode(hash("sha256", uniqid(mt_rand(1000, 9999)
.microtime(), true), true));

The array that stores CSRF tokens mapped against the Session is added to the Session through the line mentioned below, so that it is accessible from other server-side files throughout the Session:
$_SESSION['csrfTokenArray'] = $csrfTokenArray;



   3. The CSRF Token for the session is retrieved using an AJAX call, and when the user fills the form and clicks the Insert button, the form details are submitted to the pointed validate_token.php.

   Add User Page:

   add_user.html:




























When the form body is loading the JavaScript function getCSRFToken() is called, and this function makes the above mentioned AJAX POST call to the server-side token_dispatcher.php to retrieve the CSRF Token generated for the current user's current session. The JSON response returned from the server-side is taken, and when the form has completely loaded as checked by the document.readyState if statement, a new hidden input field is added to the form, and this input field contains the retrieved CSRF token which is to be passed to the server-side in the attempt in enabling the server to recognize whether the request is legitimate or not.

   4. When the client-side makes the AJAX call to the server-side, if there is a Session, the CSRF Token for that particular Session is returned to the client-side in JSON format.

   token_dispatcher.php:


token_dispatcher.php checks whether the request is POST and checks to see whether the PHPSESSID which is the PHP Session Id has been set, and if these conditions are met, it retrieves the associative array stored in the Session and returns the CSRF Token for that particular Session identified by the Session Id, along with the 200 message status and a message in the JSON format.

   5. When the form details are submitted to validate_token.php on Insert button click, the CSRF Token values will be compared and validated, and a message will be returned based on the outcome of the comparison.

   validate_token.php:


It performs the same checks previously carried out in token_dispatcher.php, but this time, additionally, the check to see whether a value has been set as the 'csrf_token' is enabled, and if it has been set, the CSRF Token value stored in the array for that particular Session is compared with the value sent in the POST request to see whether the values are equal and the request is legitimate. Either a successful message as in the picture included below, or an error message will be displayed in the client-side based on the equality comparison outcome.


One of the major drawbacks of the Synchronized Token Pattern is that it requires a lot of database space to store all the CSRF tokens generated per each user's each session. Double Submit Cookies Pattern is a better alternative to prevent CSRF while overcoming this storage issue, and I will discuss about Double Submit Cookies Pattern in my next post.

Thursday, September 13, 2018

Cross-Site Request Forgery (CSRF)

Cross-Site Request Forgery (CSRF) occurs when an attacker makes a victim perform malicious activity by making a user of a web application visit another website while browsing the application. This makes it cross-site, and it happens because the browser sends the cookies of that particular domain along with the request. This behaviour of the browser will enable the attacker to take advantage, and perform illegitimate requests using the Session Id of the user's session which is valid, making it impossible for the application to recognize whether it is a legitimate request or not.

For example, attackers can make users visit a gossip site by sending a link while the user is browsing a site, and this gossip link could lead to a page which has an image tag which does not really show any image, but contains a link to another site as in the tag mentioned below.

    <img src="https://..." width="0" height="0">

The image will not be visible as the width and height is zero, but the link will be called.

The attackers can also shorten the correct URL of a website to make the link look legitimate and trustable.

Making server shutdown requests, or unfriending people on a social website are some other examples of the malicious activities that can be performed.

This is possible only because the request made is a GET request. Therefore, any state-changing operation in the system which either can change data or the behaviour of the system must not be implemented using the HTTP GET method. Instead, methods like POST and PUT must be used.

Although some attack scenarios can be prevented by following this security best practice, it is still possible for attackers to attack through POST and PUT methods in certain circumstances.

For instance, an attacker can make an Administrator create a user account for the attacker by sending a link to the admin which will redirect the admin to a page with a form with hidden fields. This form will contain user information which will not be visible to the admin, and this form may contain a  misleading button which will visible to the user and make the user submit the form, or a button click event may be triggered through JavaScript when the form loads, making the user submit the form with a valid Session Id sent along with the request. Since session cookie goes along with the request, as mentioned before, the server will not be able to distinguish whether the request is legitimate or not. 

The picture included below illustrates the basic flow of this process I have explained above:



























There are several ways that can be used to protect web applications from CSRF. Synchronized Token Pattern and Double Submit Cookies Pattern are two of these methods I will discuss in the future.

Wednesday, September 5, 2018

Basics of Neo4j (Part I)

Introduction to Neo4j

Previously, I made a post on MongoDB which is a NoSQL database.

Similarly, Neo4j is also a NoSQL database which can be used to store unstructured data. 

There are four types of NoSQL databases: Document databases, Key-value stores, Wide-column stores, and Graph databases.

MongoDB is a Document database while Neo4j falls under the Graph database category.

As the word graph suggests, Neo4j helps in storing data in the form of graphs where nodes can be drawn and connected by edges to form the graphical structure. It also assists in visualizing data.

The query language used to carry out operations in Neo4j is called Cypher.

We can create nodes and relationships in the database to store data as mentioned above. The nodes can be labelled, and these labels can be used to recognize entities similar to the names of a table in a relational database. Although there can be only one table for one entity in SQL databases, several nodes can be created with the same label in Neo4j. Each of these nodes can store data in key-value pairs. Relationships can also be labelled, and they can also store data in the form of key-value pairs. These key-value pairs are called the properties of a node or relationship. Therefore, when compared to a relational database, a node can be considered to be more like a single record of an entity where each record can be connected to other records. The key-value pairs that can be stored in each node and relationship can differ from the other nodes and relationships with the same label which means there is no fixed structure or schema for a node or relationship with a particular label, making it possible to store any and only the information we need in each node and relationship.

You can download Neo4j Community Server by visiting the link. Run the command: neo4j console in administrator mode to start the database if you are using Windows.

Basic Cypher Commands related to Nodes

How to create a node in Neo4j?

              CREATE (a:Student {name:"Dinusha", country:"Sri Lanka"})
      RETURN a

CREATE command can be used to create a node. The parentheses () indicates that it is a node. a is used as a variable. The query works without a variable too like (:Student). Variables can be used if we want to recognize a particular node at a later moment in the query. For instance, it is used in the RETURN command which is used to retrieve and display or view the created node. The command above will create a node with Student label having the key-value pairs inside the curly braces {}, separated by commas where the key and the value of a pair is separated by a colon : .

The command above will create a node in the database and return it as in the picture below:



How to match and retrieve an existing node in Neo4j?

There are two queries that can be used to perform this action.

   1.

     MATCH (a:Student) 
     WHERE a.name = "Dinusha" 
     RETURN a

MATCH is used to make a match against the existing data, where in this case it is carried out against a node. This query uses the WHERE clause to filter out the node using the value of the key:name. The WHERE clause in Cypher is similar to the WHERE clause in SQL statements.

  2.
     MATCH (a:Student{name:"Dinusha"}) 
     RETURN a

Without using the WHERE clause, this query utilizes the capability of providing key-value pair properties in the node, to match and filter out the node.

As in the SQL databases, make sure to use a key for querying if you want to retrieve a unique record, as using other attributes can return multiple values which matched the query.

Both these queries will return an output similar to the one in the picture above.

How to update the value of an existing key of a node in Neo4j?


   MATCH (a:Student{name:"Dinusha"}) 
   SET a.name="Thiwanthi" 
   RETURN a

Similar to the update statement used in SQL, Cypher also uses the SET command to update the value of an existing key.

How to update a node by adding a new key-value pair?

   MATCH (a:Student{name:"Dinusha"}) 
   SET a.university="SLIIT" 
   RETURN a

A new key-value pair can be added the same way by using the SET command.

Please note that both the update queries exhibited above can be executed using the WHERE clause instead of mentioning the property in the node as in the previous MATCH example. The WHERE clause must be positioned above the SET command if it was to be used.

Monday, May 1, 2017

Testing an Express JS Application

We can use mocha, should, and supertest to test an express.js application. Mocha is used in creating test cases when unit testing, and executing them in a serial manner. Should is used to ensure that the response body is an Object, and have a property named _id. Supertest is used to test and ensure that the http calls are working properly.

As the first step in doing this, install mocha, should, and supertest by giving the commands:

    npm install mocha --save-dev
    npm install should --save-dev
    npm install supertest --save-dev

Then, make a new file with the name format <noun-name>.route.test.js. For example, it can be something like employee.route.test.js, and afterwards, go to the package.json file, and under "scripts", add:

   "test":"mocha \"./*.test.js\""

Then, import these three modules to the newly created file by using the require command.

Since we need the application for unit testing, we need to import that file as well. In order to do this, first go to the JavaScript file which has the application, and at the end of the file add the following line of code, so we could import the application later on, and use it.

   module.exports=app;

What we do here is, export the application made out of express, so that we could use it in unit testing. Note that app used in the above command should be the variable name given to the application made out of express using the command: const app=express();

After this step, import this file in the test file by giving the command(consider application file name to be server.js):  
   const app=require('./server');

Next step is to create the application using supertest by giving the command:
 const agent=request.agent(app);

Note that the name given in the place of the word request in the above command should be the variable name given when importing supertest using the line: const request=require('supertest');

What comes next is creating the basic structure for unit testing. The following command is given next in order to do that. Actually, what happens here is, a test suite is created. Ideally, a file should have only one test suite, but there can be cases where there is more than one test suite in a file.

  describe('Employee route test', ()=>{
    //place code here
});

Now we have to create a sample employee object to be used in testing the application. The following code will carry out that task, and it should be placed inside describe() where I have indicated by placing the comment: place code here.

 const employee={
   name:'Mary',
   email:'mary@gmail.com',
   tel:'1111111'
};

it() is used in creating test cases. Several test cases can be placed inside the test suite as we normally do. Now let's place our first test case inside the test suite. In this test case, we will be testing the POST rest method which we are using to insert an employee. The following test case code should appear below the above piece of code inside describe() in the file.

  it('should add new employee', (done)=>{
     agent.post('/employees')
         .send(employee) //parameters to be sent in the request body
        //which in this case is the sample employee object created           //above to test the inserting part of the application
         .expect(201)  //usual ok=>200 so if we have not added               //success response as 201, it is 200, depending on what you         //have used in the GET implementation in the application             //file.  
        //next comes the assertion part.
        .end(function(err, res){
           if(err){
               return done(err);
           }

           res.body.should.be.an.Object().and.have.property('_id');
           //this line expects and ensures that the body is an                  //Object and have a property named _id.

           done(); //used to signal mocha that the test case has                //been executed and that it can shift to the next test              //case in line to continue testing.
        });

      after(done=>{
           EmployeeModel.remove().then(()=>done()).catch(done);
      });
 })

The test case can now be tested to see whether it passes the test. In the same way, test cases to test other http methods can be written and tested in this test suite.