March 7, 2012

/* TODO */

   Google authentication for my system is done, BUT during the implementation, some problems / questions raised, so let's take a look and try to answer them:

       1. Yesterday night while I was working on a totally different project, I was wondering if I can access the data from the database via GET method on the browser even though I'm not authenticated, and after trying I found out that I could :) because I forgot to set the security constraint on my system. To solve this issues I google it and I found out that Java web applications for Google App Engine use a deployment descriptor file to determine how URLs map to servlets, which URLs require authentication, and other information. This file is named web.xml, and resides in the app's WAR under the WEB-INF/ directory. web.xml is part of the servlet standard for web applications. In this file I added a <security-constraint> element who defines a security constraint for URLs that match a pattern. If a user accesses a URL whose path has a security constraint and the user is not signed in, App Engine redirects the user to the Google Accounts sign-in page. Google Accounts redirects the user back to the application URL after successfully signing in or registering a new account. The app does not need to do anything else to ensure that only signed-in users can access the URL.[Source] Below is the code that I had to add to fix this bug.
<security-constraint>
      <web-resource-collection>
            <url-pattern>/api/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
            <role-name>*</role-name>
      </auth-constraint>
</security-constraint>
       2. Currently to distinguish the data between clients I've added beside their data, two more fields, the email address and the userid. Those kind of information(which by the way is unique) help me to easily get their data after logging into the system. Below you can see a snapshot of how I  did it.
/* Get the instance of the Database */
PersistenceManager db = PMF.get().getPersistenceManager();
/* Create the Sql query */
Query q = db.newQuery("select from " + Note.class.getName()
          + " where userId=='" + user.getUserId()
          + "' && emailAddress=='" + user.getEmail()
          + "' " + " order by date");
/* Execute the query */
List<Note> list = (List<Note>) q.execute();
  • On the other side my mentors said that this approach is good, BUT a correct one should use the power of Multitenancy which is supported by the Google App Engine Api. Basically multitenancy is the name given to a software architecture in which one instance of an application, running on a remote server, serves many client organizations (also known as tenants). Using a multitenant architecture simplifies administration and provisioning of tenants. You can provide a more streamlined, customized user experience, and also aggregate different silos of data under a single database schema. As a result, the application becomes more scalable. Data becomes easier to segregate and analyze across tenants because all tenants share the same database schema[Source]. Below I've added an example of creating a namespace for an authenticated user.
if (NamespaceManager.get() == null) {
  // Assuming there is a logged in user.
  namespace = UserServiceFactory.getUserService().
              getCurrentUser().getUserId();
  NamespaceManager.set(namespace);
}
       I will try to add this feature to my system, so this it will be another task on my TODO list.

       3. A small modification on the server side application that I should do, is to allow a user to edit their entries(Tasks), so all CRUD functions will be met.

Ok so let's point the main tasks that I should solve in the near future:
  • Allow an user to edit their's entries.
  • Add Multitenancy.
  • ! Add C2DM protocol, that will push notifications to client when something change on the server side.
P.S. The Demo is available on this link. It's just an small application that will prove the functionalities of the system.

No comments:

Post a Comment