Saturday, May 14, 2016

Hiphello. Adding a quick note to say that I uploaded my Hello World version of JHipster, hiphello to Github. Points of interest of the /jdl directory off the route that contains my jhipster-uml jdl model to kick start the app's entity model. I also have an example of loading 1 row into each of my entities in the /src/main/resources/config/liquibase directory.

Docker. By the way, a nice way to test this without having to stand up postgres (my db for the app) is to use docker. If you have docker installed you simply type in the following commands:

./gradlew bootRepackage -Pprod buildDocker

docker-compose -f src/main/docker/app.yml up

Mail. Another handy tool to test the mail capabilities is FakeSMTP. I ignored mail in my learning app until I needed to change a password. I realized a quick way to to get this done was to have the change password email send out to drive the user (me) back in with the change password token. FakeSMPT has a nice GUI to show incoming mail and display it or just watch an incoming mail directory that you specify. Displaying the email for the GUI invokes your OS handler for files with a ".eml" extension. In my case it kicked off MS Office's Outlook application which I haven't used for years and was hooked to my gmail account. It then tried to pull ALL of my gmail mail. Not good, be forewarned, know what .eml handling will do. On another note, their is a docker file for FakeSMTP which by default fires up the server mode. I wouldn't mind seeing FakeSMTP included in the jhipster generator and if I have an opportunity to figure out how to incorporate at a level that makes sense for the jhipster community, I may do the fork/pull request thing.

FakeSMTP Alternatives. @Fotozik on twitter alerted me to Maildev, a javascript/npm package that does essentially the same thing as FakeSMTP but uses a web page to show output emails. Works nice with HTML email that JHipster kicks out. The Maildev code is at Github. Installation:

npm install -g maildev

For unit testing the subethasmtp project has a subproject call Wiser. Wiser allows you to start and test incoming smtp email in a unit test.

Thursday, May 12, 2016

Multi-tenancy and Security. In reviewing the needs of the learning app I am developing with JHipster, I stumbled on a somewhat large-ish disconnect in terms of security. JHipster integrates Spring Secirity which offers role based authorization (authz) and a variety of social sign on options. Its pretty complete right out of the box (that JHipster generates). This is all good, but my app is being built as a multi-tenant app. When a user logs in, I not only need to make sure they have the right roles, but I also have to determine their association with a "tenant".

Multi-tenancy Model. For my application I have chose a multi-tenancy model where the application and database are shared by ALL tenants. It will be up to the code to ensure that I don't co-mingle a particular tenant's data. In my example from prior articles, I used an Employee - Department set of entities to discuss relationships. Imagine now that I need to restrict users of my learning app to a single company. The Company entity is now the driving entity as to what makes up a tenant. All other non-system entities that are part of the app (Employee, Department) have to relate to the Company such that when a user logs in, they only see the data for their company. Found a cool tool to do diagramming:

In reviewing how JHipster manages authorizations, I found that the code generated will lock down the back end access at the Rest api level by adding authorization checks at the Rest url level within the SecurityConfiguration class. I really like this approach. It frees the remainder of the app from checking roles at each step. I will still likely include spring security annotations @Pre and @Post Authorize in my high level service methods on my custom services where appropriate. I went ahead and set ALL the generated Rest apis to ROLE_ADMIN to lock them down. I really want to dig into the Spring Security expression based access control. It looks to have some pretty compelling features that might come in handy when locking down data for multi-tenancy.

Data vs. Role Security. In addition to the Role based auths however, I still have to ensure that my Rest api does not allow data from one tenant (Company) be seen by the user associated with another tenant. I went ahead and implemented my own version of UserDetails by extending User and populated it in my custom UserDetailsService. I included the notion of the Tenant in my UserDetails class such that when a user logs in and Spring calls the UserDetailsService, I load the user's default tenant (company) from the database into the UserDetails class. For now I will rely on passing the UserDetails via parameters to the Service and Repository layers to restrict data for a given user. I may refactor to use a ThreadLocal but there are many documented disadvantages to this.

JHipster and Groovy. As I begin to lay in new code, I wanted to start using Groovy. My plan is to leave the generated Java code AS Java (rather than convert to Groovy), but any new classes will be Groovy. One very minor snag is that the Groovy compiler wants all sources, Java and Groovy to be in src/main/groovy. Added these two lines to the Gradle build to fix: