Categories
Blog Posts

Authentication & Security

Authentication is the act of proving an assertion, such as the identity of a computer system user.

Wikipedia

This week, I’m working on authentication for our capstone project. My first experience with auth involved securing API routes using Auth0 during my Cloud Applications Development course. In this blog post, I’d like to discuss how Auth0 acts like a middleman to authenticate users, how it secures user data, and why developers should consider outsourcing their app security to a company like Auth0.

Auth0 is a platform that handles the complicated process of authenticating users. Administrators configure Auth0 to handle user logins by choosing the type of login to allow i.e. Google, Apple, username/password, etc. Then admins simply provide Auth0 with URL redirects for successful logins and for unsuccessful logins. Auth0 essentially becomes a middleman and the app flow looks like this: a user attempts to login on your website and is sent to an Auth0 login form. Once authenticated, Auth0 sends them back to your website using the specified redirect URL. Generally a cookie is stored locally to confirm to your app that they are authenticated. Under the hood, Auth0 secures sensitive data like usernames and passwords in AWS by salting and hashing data using bcrypt. What is salting and hashing anyway?

Salting hashes sounds like one of the steps of a hash browns recipe, but in cryptography, the expression refers to adding random data to the input of a hash function to guarantee a unique output, the hash, even when the inputs are the same.

Auth0

Let’s look at a real life example of what happens when we hash passwords without a salt. Looking at the 2012 LinkedIn Hash Dump Analysis, 1.13 million people used the password “123456”. If a bad actor decrypts this one hash, he or she now has a password that works for over one million accounts. Hence, salting helps to eliminate duplicate hashes, thereby increasing the security of all your user accounts.

In addition to salting and hashing, Auth0 encrypts this data at rest in the MongoDB database and in motion (during the back and forth requests between Auth0 and the database). It uses a cyrptographic protocol called Transport Layer Security (TLS) with at least 128 bit encryption. This simply means that the length of the key to encrypt the data is at least 128 bits and generally up to 256 bits. While this sounds complicated, there are libraries to help developers with encryption, so why don’t we all just build our own home grown authentication solutions?

One big downside to individually handling authentication is responsibility. The developer is now responsible for all the security and maintenance of the authentication system. This means that every time security best practices change around password hashing or storing user data, the solution must evolve. Depending on the size of your company or developer team, this could be very doable or a major headache.

For our capstone project, we are building an application for a small business that needs authentication for its employees. Luckily, Auth0 has a free tier when you have less than 7,000 users, which is perfect for a small business. Outsourcing security to the professionals frees up our developer team to spend more time solving business problems, ensures tighter software security, and overall is the optimal solution for our use case.

Categories
Blog Posts

ORM to the Rescue!

Last week I shared that I was feeling overwhelmed. I’m responsible for the REST API for our project. If you recall, I mentioned that our project requires CRUD operations for 14 different services, each requiring 10 – 15 pieces of information. The thought of manually validating that much data was mind boggling. I needed structure and fast! So I took some time to research Object Relational Mapping or ORM.

I had heard of Object Relational Mapping during both my databases and cloud courses. Essentially, I was told not to use it. I’m a little disheartened that no one taught it to us. I found a library called gstore-node that allows me to create schemas for each of my fourteen services, and it integrates with Datastore, simplifying the query process. Here’s some example code from my cloud portfolio project using Datastore. I really hated this code but I didn’t know to improve it at the time. Also please notice how this code is in a file containing 300 lines of code!

This single request handles authentication, errors, validates data, stores data in the database, retrieves stored data, builds responses, sets status codes, etc.

After reading the gstore-node documentation and reviewing several sample projects, I finally started to understand best practices. I separated each pest control service (i.e. feature) into their own directories containing a model, controller, and router. I read that this method is preferable to having three directories named model, controller, and router containing several feature files. For more information, follow this link.

As I began work on the next service, I realized that roach.controller.js contains the same logic for every single feature. So I removed that file into it’s own controller directory and changed the function names to be more generic.

I removed roach.controller.js and placed it in it’s own directory.

Now to the server code… compare my previous portfolio project POST request without an ORM to my current POST request using gstore-node. The entire file is 19 lines of code.

Requests are simplified by using models and controllers to handle each step.
The model structures the data, using type checking and required flags to ensure data is accurate before it is saved in the database.
The controller’s purpose is to control data flow into the model object, and also to return the response. If I was using “views”, it would also update the view.

It certainly helps to separate code blocks into files, but hopefully you can see how the ORM does the heavy lifting. The largest file here contains only 55 lines of code, instead of hundreds. Functions like sanitize(), save(), update(), schema(), and plain() abstract away extra steps that cluttered my cloud portfolio project. Though it took me a few days to learn gstore-node and get my first working route, I spent about five minutes on the second route. Now I feel confident that I can knock out 12 more including testing and documentation in an hour or two. That’s the power of using an ORM. There is an upfront cost but it’s so much simpler in the long run. There is a better way, and the way is Object Relational Mapping.

Categories
Blog Posts

Smart Bid Calculator

For our Capstone project, my team chose to build an application for my brother’s small business. I neglected to consider that we would have to do all the requirements gathering for the project. Have I mentioned that I despise requirements gathering? Once you really delve into the nitty gritty, somehow the project expands and becomes a herculean task.

My brother Ryan made the project sound easy. A mobile app for Smart Pest technicians to enter in data and a web app for business personnel to generate accurate bids. I love building software projects, creating something out of nothing, helping solve business problems… I was sold. Our professor didn’t think it would be a big enough project. I had to convince him to let three people work on it.

At our first meeting, Ryan showed us the Excel spreadsheets housing his data and business logic. Holy crap. He sent us over documentation on the lead information that techs need to obtain. Initially Ryan said there were only a handful of services. Now we’re looking at fourteen different services requiring 10-15 pieces of information for each service. Technically, I don’t think it’s hard to do, my issue is the volume of information we need to obtain and store.

I thought it would be easy to web scrape current materials pricing so that Ryan wouldn’t have to do it manually anymore. I failed to realized they have upwards of 60 different materials from multiple suppliers. Needless to say I’m feeling overwhelmed. So I took a step back and realized that the business already has a solution for generating bids. It’s lame that they have so much manual data entry but it’s functional. At a minimum, my brother needs a tire swing, not a roller coaster. We changed our goals but I’m still hopeful we can deliver everything. If we can’t, we’ll at least deliver a minimum viable product that will eliminate inefficiencies in the business while letting our team maintain sanity. Sanity is good.

Categories
Blog Posts

Teamwork

Like every human being on the planet, I too have had challenging experiences with teamwork. As the Capstone course is entirely composed of a group project, I’d like to share some tools I’ve learned that have helped to mitigate the consequences of difficult team dynamics. My top three favorite tools are team standards, communication, and vulnerability.

I was taught team standards during my coursework at OSU. This is a written document created at the start of a group project. It contains a plan for the group including methods to help resolve conflict, mutually agreed upon before everyone starts tearing their hair out. For my Software Engineering II course, I participated in a group project with my good friend Ronny and another student, let’s call him Jay. When setting up the standards, I rather arbitrarily suggested we have a conflict resolution strategy that the majority rules. This one sentence in our standards document saved our proverbial bacon.

We were each given one problem to solve with the constraint that we weren’t allowed to use built-in methods or Python modules in our code. In addition, we had to create our own black box, white box, and random testing suites for each problem. I was responsible for reviewing Jay’s code when I found an issue with his algorithm. It was taking over 20 minutes to run 1,000 random inputs. The instructor stated he would be testing 10,000 inputs for each problem and each testing suite had to finish in less than a few hours time. In my code review I recommended that Jay optimize his algorithm so that we wouldn’t lose points but he stated that it couldn’t be done.

I reviewed the algorithm Jay wrote to calculate the month, day, and year given the number of seconds since Unix epoch. I realized that there was a simpler way to perform this calculation. Jay was iterating through each day, then incrementing month and year. It seemed simpler to me to reverse the algorithm. Start by checking if the current year (set to epoch 1970) is a leap year, if not, subtract 365 days from the remaining days. By decrementing a year at a time, it saved us 365 times through the loop. Jay refused to work on the optimized version so I refactored his code using this simpler approach. Jay had the most difficult algorithm to be sure, and I believed he was having trouble asking for help. Though it took several hours to fix, we went from running 1,000 test cases in 22 minutes to running 1,000 test cases in 2 seconds.

I brought the optimized code to my group and Jay stated that he didn’t want to use it. I knew it would surely get us all the 4.0 grades we wanted, whereas Jay’s code was an unknown. I tried to communicate this with Jay but he was adamantly against using the optimized code. My second teammate and I decided to accept my PR since the majority rules in our team standard. We received a 100% on the project and all got A’s in the course.

“Teamwork begins by building trust. And the only way to do that is to overcome our need for invulnerability.”

– Patrick Lencioni

Truthfully, I don’t understand why we had to fall back on a “majority rules” standard in this case. Teamwork is a difficult balance. Was I being pushy or domineering? Solely focused on optimized code to ensure my own end goal, an A in the course? Was Jay being prideful or lazy? Not willing to put forth the effort or accept help from his team to ensure everyone’s success?

I don’t think life is ever so black and white. There are plenty of shades of gray here. I just hope that I can do my best to follow our group standards, keep the lines of communication open, and stay humble throughout this Capstone course. Worst case scenario, I have another example for interviews to discuss how I, hopefully, mitigated conflict 🙂

Categories
Blog Posts

FAANG and Capstone

I wasn’t planning to take Capstone until the spring. Last summer, I completed a subpar internship with Cigna and shortly thereafter received a return offer for an August, 2022 start date. I could technically graduate in March but why rush? I had no other prospects because I kept failing technical interviews, until something magical happened… I got lucky. While interning with Amazon, my OSU classmate referred me for a new grad position. Last year, I made it to the final round interview with Amazon and thoroughly bombed it. This year, after failing six consecutive interviews with other companies, my hopes were not high.

 

 

I was leetcoding 3-4 hours a day, stressing out, letting my grades slip, when my friend reached out with some news. He learned that some of the new grad hires were not being put through three rounds of arduous technical interviews. Due to COVID, they simply had to review their online assessment (OA) code with the interviewer. When I heard this news, I knew I had a chance. However, to my horror, my OA code was an absolute mess. After completing 15 OAs only to bomb every interview, I assumed no one was reading my perfect OA code, and I’ll admit, I became sloppy.

 

The interviewer didn’t ask me a single question about myself. He introduced himself and asked me to explain my code. I could tell he was not impressed. I explained my thought process for each problem and how I had mistakenly prioritized speed over clean code. I informed him that I had reworked each problem but he didn’t want to see the revised versions. Then he asked if I had any questions. This was my shot in the dark chance of making up for my messy code.

 

Revised Amazon OA code

 

What’s the single thing everyone in the world loves to talk about? Here’s a hint, it’s not the weather! I pestered him with thoughtful questions about his work, his opinions on Amazon, anything that seemed to interest him. Meanwhile, if I found a commonality, I promoted myself: “oh you’re studying for the AWS Solutions Architect exam? I just completed the AWS Cloud Practitioner Certification…” I absolutely gave it my all for those remaining ten minutes and then it was over.

 

I grieved the loss of that Amazon paycheck for five days. I cried every single day, I knew I bombed yet another chance to rise to the top. Two weeks later, I was in a Zoom call with my boss when I received a text message from Amazon congratulating me and instructing me to check the student portal. I nearly fainted, I was sure it was a mistake. One of those damn robo texts feeding off my desire to succeed. I logged into the portal and found an offer letter. I had done it, somehow I had convinced that interviewer to overlook my flawed code and give me a chance. Success!

 

Amazon let me choose my start date. I realized I could graduate in March and be an employed software engineer by April. Now that I had a job lined up, I could face my burn out from school and all that leetcode. I joined the millions of other Americans quitting their shitty part time jobs and decided to coast until graduation. They say that luck favors the prepared. I was not prepared and yet, I still got lucky. As my brother would say, take the win Ash, take the win.