<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Gaslight Blog</title>
    <description>We build web and mobile apps in Cincinnati, Ohio. This is our blog.</description>
    <link>https://teamgaslight.com/blog</link>
    <item>
      <title>Oh, to be a Domain Expert … if we only knew what you knew.</title>
      <author>Kati Best</author>
      <description>
        <![CDATA[<p>Let me ask you something assuming I know your industry… how long have you been in this business? I’m guessing a long time - you know what makes your world go round. You are what we refer to as a subject-matter expert (SME), the person of authority in a particular area or topic - your business. The term domain expert is frequently used in expert systems software development, and always refers to the domain other than the software domain. We are software experts, but you are the expert in the domain. </p>

<p>Do you want to know the most important aspect of our partnership? It’s the transfer of that knowledge from you to us. We have so many clients say, “This stuff is easy!” or, “What we do is simple.” Let me tell you why this transfer is essential. </p>

<p>These statements are coming from someone who works in it every single day, thinks about it all the time, and for how many years now? Wouldn’t want your software team to think and feel like they are in the weeds on the daily as well? We need your help to bring us up to your level so that we can make more informed decisions in the development and design processes. Every line of code is a decision and the more frequent access we have to clients, the better the decisions are and the quicker the feedback. This should be an iterative process intended to build shared understanding throughout the engagement.</p>

<p>Now What happens if it&rsquo;s not done well? We usually end up making assumptions and possibly building the wrong thing. Translation: delays on development, reduced productivity, and nobody wants that!</p>

<p>So teach us everything you know one step at a time, and we’ll make something great together. </p>
]]>
      </description>
      <pubDate>Wed, 11 Sep 2019 08:48:30 -0400</pubDate>
      <link>https://teamgaslight.com/blog/oh-to-be-a-domain-expert-dot-dot-dot-if-we-only-knew-what-you-knew</link>
      <guid>https://teamgaslight.com/blog/oh-to-be-a-domain-expert-dot-dot-dot-if-we-only-knew-what-you-knew</guid>
    </item>
    <item>
      <title>Gaslight, Your Partner in Growth </title>
      <author>Steve Hennegan</author>
      <description>
        <![CDATA[<p>We have all heard the phrase, “You get what you pay for,” right? When it comes to products or services - we are told you can only pick two of the three options: Fast, Cheap, and Good. Well, the crowded space of software development is no different… </p>

<p>Gaslight is a ten year old custom software development and UI/UX design consultancy in Cincinnati, OH. At ten years, you have to understand your competition and be true to your core values. There are plenty of companies out there that build software - some do it well and some don’t. There are equally plenty of consulting companies that give great advice and some… not so much. What makes Gaslight unique is that we have been very intentional about being the very best at both. At our core, we build world-class software that is flexible and scalable to adapt to the changes your business will undoubtedly go through. We have also assembled our technical teams that are eager to communicate and consult the client throughout the length of the project, and many times, beyond it. We want our team to have a strong connection to our clients to understand their goals and objectives. </p>

<p>At Gaslight we feel that we have so much to offer our clients. It starts with building a trusted relationship, and acting as advisors to build the software our clients deserve. </p>

<p>Often times, development companies claim to be consultancies, but in this business actions speak louder than words! Let me walk you through our process and give you some insight into the people you will be working with and the sessions we like to go through to deliver the most value to our clients. Before you know us, we have to get to know you. As the Sales Director here at Gaslight I am tasked with finding organizations that could benefit the most from working with Gaslight. </p>

<p>Here are some of the things I look for: 
<ul>
   <li>Organizations in “Growth Mode”</li>
   <li>Companies that know they need to innovate, but aren’t sure how or where to start</li>
   <li>Organizations that have fallen behind competition in their space due to lack of technology innovations</li>
   <li>Companies in an industry that have narrow margins where we can give them a competitive advantage by building software that makes their business run more efficiently</li>
   <li>Companies that have an opportunity to give their users a better experience (UX) </li>
   <li>Companies who have a development team who “keeps the lights on” but need an outside team to come in and help them build new innovative functions and features </li>
    <li>Start-ups looking to build an industry disrupting product </li>
</ul>
After I find these companies, that’s when the real fun begins. Let’s have a face to face meeting with you and your team to understand your business, the challenges you have, your competitors, and what makes you unique. Throughout this conversation I am going to push you to think “big picture” because my goal is to help you find your “WHY”. Building custom software is difficult and can be a major investment, so I want to make sure you and your team believe in what you are doing. I also want to make sure your team understands the opportunity that you have in front of you. We know every project is complex and unique, but we approach each one with these four things in mind. </p>

<p>Our clients want more than just cookie-cutter or built to spec software. Instead, we form authentic partnerships and work side by side to identify end-users’ needs and design and develop ambitious custom solutions.</p>

<ul>
   <li>Our teams are created to maximize efficiency and communication.</li>
<li>Every step together is transparent so that our clients are in the best position to make good decisions.</li>
<li>We craft software that works better, lasts longer, and is easier to use, maintain and modify.</li>
<li>We work to leave a lasting impact on the communities we engage with.</li>
</ul>

<p>Our approach is tried and true… but we feel that to be successful we really need to be your strategic partner in growth. We know that project success is largely correlated to the relationship we build with our clients and our understanding of their business. We will only build things that we wholeheartedly believe will help you achieve your business goals &amp; objectives. </p>
]]>
      </description>
      <pubDate>Mon, 19 Aug 2019 15:24:40 -0400</pubDate>
      <link>https://teamgaslight.com/blog/gaslight-your-partner-in-growth</link>
      <guid>https://teamgaslight.com/blog/gaslight-your-partner-in-growth</guid>
    </item>
    <item>
      <title>Refactoring Patterns in Elixir: Replace Conditional with Polymorphism Via Protocols Part 2</title>
      <author>Zack Kayser</author>
      <description>
        <![CDATA[<h2>Part 2: Replace Conditionals with Polymorphism Via Protocols</h2>

<p><em>Use Elixir protocols to bring polymorphism to your data structures</em></p>

<p>This is the second in a series of posts we are doing on refactoring patterns in Elixir, a series that stemmed from working through Martin Fowler&rsquo;s book <em>Refactoring</em>. In the first part of this series, we looked at using pattern matching in function heads as a tool to use for refactoring complex conditionals.</p>

<p>Pattern matching is ubiquitous in Elixir and Erlang, and it is a great tool to use for cleaning up complex conditionals in most common cases. To recap what we did in the last post, let&rsquo;s take a look at this code sample ported over to Elixir from the JavaScript example in Martin Fowler&rsquo;s book, and then see how we were able to refactor it using pattern matching:</p>

<h3>The <code>Bird</code> module before refactoring:</h3>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">Bird</span> <span class="k">do</span>


  <span class="kd">defstruct</span> <span class="ss">type</span><span class="p">:</span> <span class="no">nil</span><span class="p">,</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="ss">voltage</span><span class="p">:</span> <span class="mi">0</span>


  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="n">bird</span><span class="p">)</span> <span class="k">do</span>
    <span class="k">case</span> <span class="n">bird</span><span class="o">.</span><span class="n">type</span> <span class="k">do</span>
      <span class="s2">&quot;EuropeanSwallow&quot;</span> <span class="o">-&gt;</span>
        <span class="s2">&quot;average&quot;</span>
      <span class="s2">&quot;AfricanSwallow&quot;</span> <span class="o">-&gt;</span>
        <span class="k">if</span> <span class="n">bird</span><span class="o">.</span><span class="n">number_of_coconuts</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="k">do</span>
          <span class="s2">&quot;tired&quot;</span>
        <span class="k">else</span>
          <span class="s2">&quot;average&quot;</span>
        <span class="k">end</span>
      <span class="s2">&quot;NorwegianParrot&quot;</span> <span class="o">-&gt;</span>
        <span class="k">if</span> <span class="n">bird</span><span class="o">.</span><span class="n">voltage</span> <span class="o">&gt;</span> <span class="mi">100</span> <span class="k">do</span>
          <span class="s2">&quot;scorched&quot;</span>
        <span class="k">else</span>
          <span class="s2">&quot;beautiful&quot;</span>
        <span class="k">end</span>
      <span class="bp">_</span> <span class="o">-&gt;</span>
        <span class="s2">&quot;average&quot;</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<h3>The <code>Bird</code> module after refactoring:</h3>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">Bird</span> <span class="k">do</span>
  <span class="kd">defstruct</span> <span class="ss">type</span><span class="p">:</span> <span class="no">nil</span><span class="p">,</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="ss">voltage</span><span class="p">:</span> <span class="mi">0</span>


  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{</span><span class="ss">type</span><span class="p">:</span> <span class="s2">&quot;AfricanSwallow&quot;</span><span class="p">,</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="n">num</span><span class="p">})</span> <span class="ow">when</span> <span class="n">num</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">,</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;tired&quot;</span>


  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{</span><span class="ss">type</span><span class="p">:</span> <span class="s2">&quot;NorwegianParrot&quot;</span><span class="p">,</span> <span class="ss">voltage</span><span class="p">:</span> <span class="n">voltage</span><span class="p">})</span> <span class="ow">when</span> <span class="n">voltage</span> <span class="o">&gt;</span> <span class="mi">100</span><span class="p">,</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;scorched&quot;</span>


  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{</span><span class="ss">type</span><span class="p">:</span> <span class="s2">&quot;NorwegianParrot&quot;</span><span class="p">}),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;beautiful&quot;</span>


  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{}),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;average&quot;</span>
<span class="k">end</span>
</pre></div>
<p>Just looking at the before and after versions of the above code snippet, we can see that pattern matching in function heads gives us a huge benefit and an easy win in the readability department. Our code is now easier to understand and reason about: with only four cases for the <code>plumage/1</code> function, we can easily find and determine what will be returned from the function for a given <code>Bird</code>.</p>

<p>We did, however, note one caveat to the refactoring tool used above: assuming we had a larger variety of <code>Bird</code>s to handle, with each variety requiring some unique logic to determine its plumage, we would naturally arrive at a situation where the shear amount of function heads that we would need to create would become overwhelming and lead to harder and harder to follow logic. Not only that, but since calls to these functions would fall through from top to bottom in the order they are declared, we would also have to think long and hard about what order to place the function heads in to arrive at the intended behavior. Eventually, we would reach a breaking point where maintaining this function would start to become intractable.</p>

<p>One solution for dealing this is actually quite simple: if we are dealing with a plethora of different kinds of <code>Bird</code> that all have different conditions that determine what their <code>plumage</code> is, then perhaps we should break away from the generic idea of a <code>Bird</code> and create data structures that are more specific and tailored to the kind of bird(s) we are actually working with. For example, given the code snippet above, maybe we want to have <code>EuropeanSwallow</code>, <code>AfricanSwallow</code>, and <code>NorwegianParrot</code> represented as data structures instead of just a <code>Bird</code> (or in addition to a <code>Bird</code> that would represent a general case).</p>

<p>Elixir actually gives us an elegant way of handling this kind of problem &ndash; protocols which you can read more about <a href="https://elixir-lang.org/getting-started/protocols.html">here</a>. Essentially, a protocol allows us to declare one function and delegate out the implementation of that based on the type of the data passed in to the function. Keeping with our <code>Bird</code> example, we might have a protocol <code>Bird.plumage/1</code> and delegate out specialized implementations of the function based on our <code>EuropeanSwallow</code>, <code>AfricanSwallow</code>, and <code>NorwegianParrot</code> data structures. Note that we can also have a fallback implementation for protocols so that we can handle generalized cases if that is what we need. Let&rsquo;s take a look at what our protocol definition looks like:</p>
<div class="highlight"><pre><span></span><span class="kd">defprotocol</span> <span class="nc">Bird</span> <span class="k">do</span>
  <span class="na">@fallback_to_any</span> <span class="no">true</span>
  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="n">bird</span><span class="p">)</span>
<span class="k">end</span>
</pre></div>
<p>There are a couple things of note here. First, defining a protocol is more or less the same as defining a module (and, in fact, this will generate a module for us), and second, we define only function heads inside of the protocol without providing an implementation. The <code>@fallback_to_any true</code> declaration tells Elixir to reference an implementation of the function it marks for the <code>Any</code> data structure. We will look at an example of that below, but for now just note that you can use this to provide a generalized fallback implementation.</p>

<p>So once we have a protocol set up, how do we define our own custom implementations of the function(s) declared in the protocol? Let&rsquo;s take a look at what our implementation would look like for the <code>NorwegianParrot</code>, and while we are at it, we will also create a module for <code>NorwegianParrot</code> and define a struct for it:</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">NorweiganParrot</span> <span class="k">do</span>
  <span class="kd">defstruct</span> <span class="ss">voltage</span><span class="p">:</span> <span class="mi">0</span>


  <span class="kd">defimpl</span> <span class="nc">Bird</span><span class="p">,</span> <span class="ss">for</span><span class="p">:</span> <span class="nc">NorweiganParrot</span> <span class="k">do</span>
    <span class="kd">def</span> <span class="n">plumage</span><span class="p">(%</span><span class="nc">NorweiganParrot</span><span class="p">{</span><span class="ss">voltage</span><span class="p">:</span> <span class="n">voltage</span><span class="p">})</span> <span class="ow">when</span> <span class="n">voltage</span> <span class="o">&gt;</span> <span class="mi">100</span><span class="p">,</span>
      <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;scorched&quot;</span>


    <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="bp">_</span><span class="p">),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;beautiful&quot;</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>And for the <code>EuropeanSwallow</code> and <code>AfricanSwallow</code>, we would have something like:</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">EuropeanSwallow</span> <span class="k">do</span>
  <span class="kd">defstruct</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="mi">0</span>


  <span class="kd">defimpl</span> <span class="nc">Bird</span><span class="p">,</span> <span class="ss">for</span><span class="p">:</span> <span class="nc">EuropeanSwallow</span> <span class="k">do</span>
    <span class="kd">def</span> <span class="n">plumage</span><span class="p">(%</span><span class="nc">EuropeanSwallow</span><span class="p">{}),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;average&quot;</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>and</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">AfricanSwallow</span> <span class="k">do</span>
  <span class="kd">defstruct</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="mi">0</span>


  <span class="kd">defimpl</span> <span class="nc">Bird</span><span class="p">,</span> <span class="ss">for</span><span class="p">:</span> <span class="nc">AfricanSwallow</span> <span class="k">do</span>
    <span class="kd">def</span> <span class="n">plumage</span><span class="p">(%</span><span class="nc">AfricanSwallow</span><span class="p">{</span><span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="n">num</span><span class="p">})</span> <span class="ow">when</span> <span class="n">num</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">,</span>
      <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;tired&quot;</span>


    <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="bp">_</span><span class="p">),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;average&quot;</span>
  <span class="k">end</span>
</pre></div>
<p>We are defining the specialized implementation for the three types of bird we are concerned with here. To do this, we use <code>defimpl #{ProtocolName}, for: #{MyDataType}</code> to let Elixir know that this is the implementation of the <code>Bird</code> protocol for the type we are passing as the value to <code>for:</code>. Just like in normal Elixir modules, we can use pattern matching and guard clauses when declaring functions, and we can also have multiple function heads for the same declaration. This is all just good ole classic Elixir.</p>

<p>The great thing about this is it gives us a much more focused, granular level of control over the way a function behaves based on the type of data it receives. We no longer have to worry about how a <code>NorwegianParrot</code>&lsquo;s plumage is calculated when we are working on our implementation of the <code>AfricanSwallow</code>.</p>

<p>As I mentioned above, we can also define a fallback implementation that will catch any parameters that are passed to <code>Bird.plumage/1</code> that don&rsquo;t match the three specialized implementations we worked out above. You can do that by defining an implementation of the protocol for the <code>Any</code> data type like this:</p>
<div class="highlight"><pre><span></span><span class="kd">defimpl</span> <span class="nc">Bird</span><span class="p">,</span> <span class="ss">for</span><span class="p">:</span> <span class="nc">Any</span> <span class="k">do</span>
  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="bp">_</span><span class="p">),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;average&quot;</span>
<span class="k">end</span>
</pre></div>
<p>With all of this in place, we can replace the initial code snippet from above with our protocol, giving us polymorphism on the parameters that get passed to <code>Bird.plumage</code> instead of relying on pattern matching in a single module and we can avoid potentially having to handle a large number of different cases in the same file. We now have more control over the behavior of the function and can write tests that can prove out different edge cases around the specialized implementations that we care about.</p>

<p>To finish this out, let&rsquo;s look at what it might look like to call this code:</p>
<div class="highlight"><pre><span></span><span class="mi">1</span><span class="o">&gt;</span> <span class="nc">Bird</span><span class="o">.</span><span class="n">plumage</span><span class="p">(%</span><span class="nc">AfricanSwallow</span><span class="p">{</span><span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="mi">7</span><span class="p">})</span> <span class="c1">### &quot;tired&quot;</span>
<span class="mi">2</span><span class="o">&gt;</span> <span class="nc">Bird</span><span class="o">.</span><span class="n">plumage</span><span class="p">(</span><span class="s2">&quot;some general bird&quot;</span><span class="p">)</span> <span class="c1">### &quot;average&quot;</span>
<span class="mi">3</span><span class="o">&gt;</span> <span class="nc">Bird</span><span class="o">.</span><span class="n">plumage</span><span class="p">(%</span><span class="nc">NorwegianParrot</span><span class="p">{</span><span class="ss">voltage</span><span class="p">:</span> <span class="mi">7000</span><span class="p">})</span> <span class="c1">### &quot;scorched&quot;</span>
</pre></div>
<p>That wraps up our second installment in our Refactoring Elixir Series. I hope you enjoyed, and happy Elixiring to you!</p>
]]>
      </description>
      <pubDate>Mon, 05 Aug 2019 15:21:34 -0400</pubDate>
      <link>https://teamgaslight.com/blog/refactoring-patterns-in-elixir-replace-conditional-with-polymorphism-via-protocols-part-2</link>
      <guid>https://teamgaslight.com/blog/refactoring-patterns-in-elixir-replace-conditional-with-polymorphism-via-protocols-part-2</guid>
    </item>
    <item>
      <title>"My life has not been the same since I started the Gaslight Apprenticeship Program." </title>
      <author>Omar Suriel</author>
      <description>
        <![CDATA[<p>Simply put, the Gaslight Software Development Apprenticeship program changed my life. I graduated high school in 2010. Which is not that long ago, at least I like to think that. But the technology landscape was totally different. mySpace was still hot, facebook wasn’t even a thing yet, blackberries were the phones to have and normal people had not seen an iPhone in person yet. Most importantly third party phones apps were not really a thing.  A few years before that, my H.S. sophomore year, I moved back to the United States. Even though I was born here, my mother moved back to the Dominican Republic as soon as she had me, so I did not speak english AT ALL, when I came back. I did not have many friends or things to do when I first came to Ohio. That lead to me starting my first website with a friend. But this is not going where you think it’s going. It is not another one of those stories where the person starts coding as a kid or teenager and the becomes a successful developer. It is quite the opposite of that. Our website did not require any programing knowledge at all. To summarize it, it was pretty much a Microsoft word file that we figured out how to put online. We ran that website for a year until I started working at McDonald’s and actually getting paid.</p>

<p>I graduated high school and I never thought of being a developer. The term web developer wasn’t even a thing back then, people use to call them webmaster or web designers. I went to college for a while (nothing related to programing) then, after a year and a half I got a decent job and dropped out of school in order to work. The business closed down soon after, so I started a couple of businesses. Some were not successful at all and some were successful for a while but not life changing. I went on to working whatever job I could get in order to pay for my rent and the bills. I worked in retail, I washed dishes, I worked at  factories, warehouses, pizza places, and everything in between. And every job I got I seemed to hate it more than the last one. The pizza places weren’t too bad but i was lucky to average $11/hr or $12/hr after tips.</p>

<p>After about 6 years working these types of jobs and many failed attempts to change my life for the better. I took things to another level and decided to learn to program. I tried learning while working full time but It just didn&rsquo;t work out for me. I felt like every weekend I was learning the same stuff. That’s because I had already forgotten everything I learned the weekend before. Eventually I came to the realization that I was doing everything backwards. I realized was putting most of my effort into the wrong things, the low paying/anybody-can-do jobs. So I quit my main job at the time and got a different job where I only worked part time, on the weekends. That allowed me to put most of my effort, Monday through Friday, into my future, becoming a developer. I followed Brian Tracy’s 12 step method to accomplish any goal: I wrote  down a new life schedule and a monthly budget that I followed religiously until I accomplished my first big goal.  Getting my first job as a developer. Since I was only working on weekends, the money was more than tight. It was 700/month to be exact. But every single dollar was accounted for.</p>

<p>After about 7 months of quitting my job and only working weekends I was finally making progress as a developer. But, at that time, I did not have any mentors who I could ask for advice or help. So I did the obvious thing to do and I googled for suggestions on how to get mentors. That led to me attending every software developer related meetup in my city and cities nearby. That’s how I found Gaslight. They seemed to have the strongest javascript following on meetup.com in the area and I started attending their events. I remember how financially taxing attending their meetups was for me at the time. It was about 3 hours round trip plus paying for expensive downtown parking. Looking back, attending these Gaslight meetups turned out to be one of the best decisions I ever made in my life and that’s not an exaggeration at all. I learned about their apprenticeship program  the first time i went, and eventually, I was told I was being considered for an apprenticeship program that coming up in about 3 to 6 month from the time I was told.</p>

<p>A few days later, I got an email from Chris Nelson (Gaslight apprenticeship manager), asking If I’d be interested to start sooner, the next Monday, due to someone else cancelling(I think, to be honest I didn’t care too much about the reason). Starting the apprenticeship at that time meant I had to move to a new city, get an apartment, etc. Even when the job wasn’t guaranteed. However, the answer was obviously yes. I drove down to Cincinnati and spoke to Chris about the all the details. I officially accepted the offer, and I acted cool and chilled until I left and got in the elevator and the doors closed. That’s when I finally got hysterical and started jumping. As corny as It may sound, I felt Chris Gardner(played by Will Smith) when he finally got the job in the last scene of the Pursuit of Happiness movie.</p>

<p>The apprenticeship put me in Kroger Digital and I had the opportunity to be part  of 2 amazing teams during my time there. There was a lot of learning, mentoring, anxiety, imposter syndrome, work, fun, etc. All of which helped me become what I like to call, a “Real Developer” and Kroger ended up making me an offer and hiring me as a full time employee.</p>

<p>In summary, my life has not been the same since I started the Gaslight apprenticeship program, and again, that is not an exaggeration at all. Now days I work as a full time, full stack developer and help other self taught developers through my youtube channel: https://www.youtube.com/omarsuriel</p>
]]>
      </description>
      <pubDate>Mon, 15 Jul 2019 10:12:33 -0400</pubDate>
      <link>https://teamgaslight.com/blog/my-life-has-not-been-the-same-since-i-started-the-gaslight-apprenticeship-program-dot</link>
      <guid>https://teamgaslight.com/blog/my-life-has-not-been-the-same-since-i-started-the-gaslight-apprenticeship-program-dot</guid>
    </item>
    <item>
      <title>We aren't servers, we are sales people! </title>
      <author>Steve Hennegan</author>
      <description>
        <![CDATA[<p>Before I came to Gaslight, I remember sitting in a company wide sales meeting with a c-level executive discussing which opportunities in our current pipeline we could close quickly to hit quarterly numbers. Then I heard, “We aren’t servers, we are salespeople.” I nodded and moved the conversation forward, but later on my commute home, I couldn’t stop thinking about the meaning behind that sentence. More importantly, what would the impact to our prospects/clients be if everyone thought this way? </p>

<p>Let me put this out into the world… I understand that my job at its core is to identify opportunities, connect a solution with our service and close the deal as soon as possible to drive revenue for my company, (wow, that seems a little cold when you actually put it on paper). In reality my day to day doesn’t seem that cold at Gaslight. On a daily basis I’m connecting with intelligent people, learning about their challenges, and helping them decide if we are the right fit to help them. So when I hear, “We aren’t servers, we are sales people,” it makes me think of the old school, 1990’s “Boiler Room” sales that they used to teach at the entry level, yuck.</p>

<p>The message that the executive was hoping to get across that board room was this; we need to persuade prospects that are uncomfortable moving forward with the project to close regardless of how comfortable they are. When a prospect is uncomfortable, they stall, and his solution to stalling - push harder. He’s hoping to remove time from the equation. In his eyes time is what gives the prospect the opportunity to find a good excuse to back out of a sale. In reality this is human nature. We as humans are pressured by imposed deadlines and find comfort in having time to review. </p>

<p>The better solution here (like most things in life) is to find a balance. Your sales team has to move opportunities through the pipeline and close them on a consistent basis. If you are using metrics to track your pipeline, you will see obvious areas where your opportunities are slowing, or fizzling out. As a sales person, this is an opportunity to self evaluate the sales process and discover what YOU are doing wrong, not what the prospect is doing wrong. There are many sales tactics and tools you can put in place with the prospect to help them stay on track, while still giving them the opportunity to step on the brakes if they are uncomfortable moving forward, my favorite tool is the “MAAP - Mutually Agreed Action Plan”. Here is a great high level overview of a MAAP and how/when to use it by Sales Hacker. </p>

<p>If you carve an opportunity down to its core and start to think about why it may be slowing down, oftentimes you’ll find a lack of trust. If there is a need, and your service or product solves that need, and there is a budget in place that reports back solid ROI numbers - then why would an opportunity stall? Lack of trust. The prospect doesn’t fully trust you and/or your company. They don’t trust the solution you have laid out for them, or the competency of the team that is going to be assigned to their project. Being in the custom software development space these are often six to seven figure decisions, and making big moves with big waves to follow doesn’t come easy for most people. In a lot of ways their job, career, and professional reputation depends on making the right decision. Understanding this weight and showing empathy towards their situation will allow you to meet the client where they stand. They aren’t looking for someone to push them, they want you to stand next to them arm and arm and walk down the path together. Making every step in unison, moving forward naturally. They want to know that you stand behind your solution, and won’t disappear if it isn’t well received. They want to know that you have their back, that this is a team effort and they won’t be stuck alone having to answer to their boss (everyone has one) as to why they chose your solution, or went with your company over others. I challenge you to walk down that path with your prospects, practice empathy, and understand that large financial decisions are uncomfortable.  </p>

<p>Obviously, there’s a place in the world for servers, and for sales people. What’s not so obvious is that you cannot rush trust. Forcing trust only benefits you temporarily to close a deal, and prospects see right through that. If you understand that building trust doesn’t come packaged in a metrics driven model, and you are genuine in helping your prospects, trust will happen naturally. And trust will give your prospects the piece of mind to make a decision and move forward with the project. Help them understand that you are setting the pace, yet they are the ones running the marathon, completely in control of the end result.  </p>

<p>I’m sure you are asking, “Ok Mr. know it all… How do I build trust and close deals quickly?” The answer is complex, but working for an organization that values doing right by their clients is the first step. <a href="https://www.amazon.com/Getting-Naked-Business-Shedding-Sabotage/dp/0787976393/ref=pd_lpo_sbs_14_t_0?_encoding=UTF8&psc=1&refRID=XM4NS0T8SCVW8J8DRREY">“Getting Naked” by Patrick Lencioni</a> is a required reading for all employees at Gaslight. Start there, and remember that doing right by the client, even if it means short-term financial sacrifice for you personally, will ALWAYS come back to you in future success! </p>

<p>My personal philosophy:</p>

<p>In sales you can frequently get bogged down by metrics and statistics, but at the end of the day all I really care about is constantly improving my ability to make my prospects and clients feel comfortable making complex decisions. Everything else will flow from that simple action. </p>
]]>
      </description>
      <pubDate>Mon, 08 Jul 2019 11:14:25 -0400</pubDate>
      <link>https://teamgaslight.com/blog/we-arent-servers-we-are-sales-people</link>
      <guid>https://teamgaslight.com/blog/we-arent-servers-we-are-sales-people</guid>
    </item>
    <item>
      <title>You don't need an app, you need a solution to your users' problems</title>
      <author>Katie Pohlman</author>
      <description>
        <![CDATA[<p>You’re looking for your next big thing, but that doesn’t necessarily need to be an app … Typically we see four organizations that fall into this, “OMG we need an app” camp. Medium sized organizations likely don’t have a CTO or technical leadership, and can have a hard time dedicating time and resources to thought leadership in that space. Non-technical markets have similar struggles and often feel late to the party when it comes to technology. We also see a lot of clients looking for better ways to engage their customers or reach new markets. Finally, as we know, competitive pressure can drive you into wanting an app. Your competitor just launched an app that claims to have shiny features, and all of a sudden you feel you need one too, without really understanding the problem you’re trying to solve. </p>

<p>So, you want to build and app? So does everyone and their uncle. </p>

<p>You aren’t the only one that feels you need an app to stay relevant in the market, but we believe it’s mistaken for table stakes. We’ve overwhelmed our users by asking them to download an app for every tiny task we want them to do. Ever heard of <a href="http://fortune.com/2016/08/16/app-fatigue-is-taking-a-toll-on-smartphone-owners/">app-fatigue?</a> Users struggle to see the value from their download, in fact, only 40 apps are used per month of 80 that are downloaded, according to annieapp.com. The average amount a company will spend on a custom app is about one million, that’s quite a bit for it to be deleted after they redeem their free gift. If you do want to spend that kind of money, it better be worth it! </p>

<p>Still want an app? Tell me why … do you simply think it’s cool? Do you think you users will enjoy it? Remember, an app only sticks when it provides continuous value to its user. (Hey, that’s one of our core values). Let’s think about what problem you are actually trying to solve, instead of launching an app that feels a lot like a bandaid over top of the struggle. If your ultimate plan to build an app has been interrupted by us, then we’ve done a good job. But we won’t leave you here with wide eyes, <a href="https://gaslight-website.s3.amazonaws.com/downloads/ama-talk-handout.pdf">download our checklist</a> to identify when an app makes sense. Maybe an app makes sense for you, maybe not. We challenge you to find a solution to fit the user’s problem, not make the problem fit your preferred solution.  </p>
]]>
      </description>
      <pubDate>Mon, 01 Jul 2019 11:18:44 -0400</pubDate>
      <link>https://teamgaslight.com/blog/you-dont-need-an-app-you-need-a-solution-to-your-users-problems</link>
      <guid>https://teamgaslight.com/blog/you-dont-need-an-app-you-need-a-solution-to-your-users-problems</guid>
    </item>
    <item>
      <title>Apprenticeship VS Outsourcing: There's Simply No Comparison </title>
      <author>Brandi Emerson</author>
      <description>
        <![CDATA[<p>Let&rsquo;s stop comparing apples to oranges &hellip; </p>

<p>People often compare the cost of an apprenticeship program to the cost of hiring an outside recruiter - but we have to be honest with you, that makes no sense! A traditional recruiter will charge a fee to find a developer, and even then, what is the criteria they use? Even if this fee is high (say $25,000), it&rsquo;s often quite a bit less than the hourly cost for six months for a mentor and two apprentices. The problem with this comparison is that it does not account for the value delivered over those six months. </p>

<p>Our apprenticeship model is about providing you with a team that produces both short-term and long-term value. In fact, this team can start delivering on your project within the first few weeks. </p>

<p><a href="https://cdn2.hubspot.net/hubfs/509988/apprenticeship-updated%20(1).pdf?utm_campaign=Apprenticeship%202.0&utm_medium=email&_hsenc=p2ANqtz-8ZBDpYgZGxFF8k9lnwJFSIcn53pHv_UUU1JEv6Z_RMd8pPOCH3sWUsvMeStAA0JnkuV1NL&utm_source=hs_email&hsCtaTracking=ee10b206-1a06-4574-a86f-ca178caed327%7C93ddb97d-f7e9-4db3-b304-e25fdbda5a5a">Download</a> our side by side comparison to see why the choice is obvious. </p>
]]>
      </description>
      <pubDate>Fri, 21 Jun 2019 09:17:01 -0400</pubDate>
      <link>https://teamgaslight.com/blog/apprenticeship-vs-outsourcing-theres-simply-no-comparison</link>
      <guid>https://teamgaslight.com/blog/apprenticeship-vs-outsourcing-theres-simply-no-comparison</guid>
    </item>
    <item>
      <title>Intro to Processes in Elixir</title>
      <author>Scott Wiggins</author>
      <description>
        <![CDATA[<h1>Intro to Processes in Elixir</h1>

<p>As I have been learning Elixir in the past few months, I have heard a lot about processes. Lots of
Elixir&rsquo;s biggest selling points, like its concurrency support, scalability, and fault tolerance, are
possible because of the features and characteristics of processes.</p>

<h2>Processing Processes</h2>

<p>Elixir runs on the Erlang VM, and processes are a core part of Erlang&rsquo;s architecture. Erlang&rsquo;s
concurrency model relies on the idea of Actors. An Actor is a self-contained process that performs a
specific task and can only communicate with other processes via message-passing. Erlang&rsquo;s processes
are incredibly lightweight and fast, spinning up in MICROseconds. This small overhead also means you
can have a lot of them at once, up to 268 million.</p>

<p>Elixir provides a lot of incredibly useful abstractions on top of Erlang&rsquo;s processes, so you don&rsquo;t
usually need to interact with them directly, but I wanted to get in the weeds a little bit. So I
made a very simple Elixir application that utilizes some of the basics of spawning processes and
message-passing. The full source code for the project can be found
<a href="https://github.com/willus10245/math_racer">here</a>.</p>

<h2>Math Racer</h2>

<p>MathRacer is a very simple and useful competitive addition application. It&rsquo;s public API is one
function: <code>MathRacer.race/1</code>. It takes an integer and spins up that number of <code>MathRacer.Adder</code>
processes, which then perform a complicated mathematical operation (1 + 2). The result and the time
it took to complete are printed to the console for each Adder, and at the end, the overall average
time to complete the operation is printed.</p>
<div class="highlight"><pre><span></span><span class="n">iex</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span><span class="o">&gt;</span> <span class="nc">MathRacer</span><span class="o">.</span><span class="n">race</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">67</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="ss">:ok</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">67</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">67</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">67</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">92</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">97</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">97</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">97</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">97</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">It</span> <span class="n">took</span> <span class="mi">97</span> <span class="n">microseconds</span> <span class="n">to</span> <span class="n">get</span> <span class="n">the</span> <span class="ss">result</span><span class="p">:</span> <span class="mi">3</span>
<span class="nc">The</span> <span class="n">average</span> <span class="n">time</span> <span class="n">was</span> <span class="mf">84.5</span> <span class="n">microseconds</span>
</pre></div>
<p>Let&rsquo;s start with the entry point of the application: <code>MathRacer.race/1</code>:</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">MathRacer</span> <span class="k">do</span>
  <span class="kd">def</span> <span class="n">race</span><span class="p">(</span><span class="n">num_of_adders</span><span class="p">)</span> <span class="ow">when</span> <span class="n">is_integer</span><span class="p">(</span><span class="n">num_of_adders</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">range</span> <span class="o">=</span> <span class="mi">1</span><span class="o">..</span><span class="n">num_of_adders</span>


    <span class="n">coordinator_pid</span> <span class="o">=</span>
      <span class="n">spawn</span><span class="p">(</span><span class="nc">MathRacer.Coordinator</span><span class="p">,</span> <span class="ss">:loop</span><span class="p">,</span> <span class="p">[[],</span> <span class="nc">Enum</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">range</span><span class="p">)])</span>


    <span class="n">range</span>
    <span class="o">|&gt;</span> <span class="nc">Enum</span><span class="o">.</span><span class="n">each</span><span class="p">(</span><span class="k">fn</span> <span class="bp">_</span> <span class="o">-&gt;</span>
      <span class="n">adder_pid</span> <span class="o">=</span> <span class="n">spawn</span><span class="p">(</span><span class="nc">MathRacer.Adder</span><span class="p">,</span> <span class="ss">:loop</span><span class="p">,</span> <span class="p">[])</span>
      <span class="n">send</span><span class="p">(</span><span class="n">adder_pid</span><span class="p">,</span> <span class="p">{</span><span class="n">coordinator_pid</span><span class="p">,</span> <span class="p">{</span><span class="ss">:add</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]},</span> <span class="ss">:erlang</span><span class="o">.</span><span class="n">timestamp</span><span class="p">()})</span>
    <span class="k">end</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>Here we see two of the functions that Elixir gives you for dealing directly with processes:
<code>spawn/3</code> and <code>send/2</code>. <code>spawn/3</code> is used to start a process. It takes a module, and atom
representing a function in that module, and a list of arguments. It starts a process by calling the
given function with list of arguments. The spawn function returns the PID (process identifier) of
the process, which is placed into a variable for later use. Two kinds of processes are spawned in
this function. One calls the <code>loop/2</code> function of the <code>MathRacer.Coordinator</code> module with an empty
list and the length of our range as arguments. The second calls the <code>loop/0</code> function of the
<code>MathRace.Adder</code> module with no arguments. We&rsquo;ll look at what these functions do later.</p>

<p>The other important function used here is <code>send/2</code>. This is how messages are sent between processes.
It is called with the PID of the process you are sending a message to, as well as the message
itself.</p>

<p>Our <code>race/1</code> function takes the number passed to it, spawns that many <code>MathRacer.Adder</code> processes
and sends them each a message in the form of a tuple containing the PID of the coordinator process,
another tuple contianing the atom <code>:add</code> and a list of two numbers, and a timestamp taken using a
function from the core Erlang module.</p>

<p>Let&rsquo;s take a look at the other side of this message sending equation. The core of our application
is the <code>MathRacer.Adder</code> module.</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">MathRacer.Adder</span> <span class="k">do</span>
  <span class="kd">def</span> <span class="n">loop</span> <span class="k">do</span>
    <span class="k">receive</span> <span class="k">do</span>
      <span class="p">{</span><span class="n">sender_pid</span><span class="p">,</span> <span class="p">{</span><span class="ss">:add</span><span class="p">,</span> <span class="p">[</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">]},</span> <span class="n">start_time</span><span class="p">}</span> <span class="o">-&gt;</span>
        <span class="n">send</span><span class="p">(</span><span class="n">sender_pid</span><span class="p">,</span> <span class="n">add</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">start_time</span><span class="p">))</span>
      <span class="bp">_</span> <span class="o">-&gt;</span>
        <span class="ss">:error</span>
    <span class="k">end</span>
  <span class="k">end</span>


  <span class="kd">def</span> <span class="n">add</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">start_time</span><span class="p">)</span> <span class="ow">when</span> <span class="n">is_number</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="ow">and</span> <span class="n">is_number</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="k">do</span>
    <span class="p">{</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">,</span> <span class="ss">:timer</span><span class="o">.</span><span class="n">now_diff</span><span class="p">(</span><span class="ss">:erlang</span><span class="o">.</span><span class="n">timestamp</span><span class="p">(),</span> <span class="n">start_time</span><span class="p">)}</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>This module contains two functions: <code>add/3</code> and <code>loop/0</code>. <code>add/3</code> is a simple function that takes
two numbers and a timestamp, and returns the sum of the two numbers and the difference between the
time it receives and the time it executes. This utilizes the <code>timer</code> module from Erlang. The
<code>now_diff/2</code> function takes two Erlang timestamps and returns the difference in microseconds.</p>

<p>The <code>loop/0</code> function is the interesting part. It contains a <code>receive</code> block. This is how an Elixir
process defines the messages it can receive. Using pattern matching, you list the kinds of messages
that your process can receive and give a default response for any unknown messages. The rest is
simple. If you send <code>MathRacer.Adder</code> the message it expects, it responds by sending the PID given
to it a message containing the result of the <code>add/3</code> function call.</p>

<p>The last piece to look at is the Coordinator module.</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">MathRacer.Coordinator</span> <span class="k">do</span>
  <span class="kd">def</span> <span class="n">loop</span><span class="p">(</span><span class="n">results</span> <span class="p">\\</span> <span class="p">[],</span> <span class="n">results_expected</span><span class="p">)</span> <span class="k">do</span>
    <span class="k">receive</span> <span class="k">do</span>
      <span class="p">{</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">sum</span><span class="p">,</span> <span class="n">time</span><span class="p">}</span> <span class="ow">when</span> <span class="n">is_number</span><span class="p">(</span><span class="n">sum</span><span class="p">)</span> <span class="ow">and</span> <span class="n">is_number</span><span class="p">(</span><span class="n">time</span><span class="p">)</span> <span class="o">-&gt;</span>
        <span class="nc">IO</span><span class="o">.</span><span class="n">puts</span><span class="p">(</span><span class="s2">&quot;It took </span><span class="si">#{</span><span class="n">time</span><span class="si">}</span><span class="s2"> microseconds to get the result: </span><span class="si">#{</span><span class="n">sum</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
        <span class="n">new_results</span> <span class="o">=</span> <span class="p">[</span><span class="n">time</span> <span class="o">|</span> <span class="n">results</span><span class="p">]</span>
        <span class="k">if</span> <span class="n">results_expected</span> <span class="o">==</span> <span class="nc">Enum</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">new_results</span><span class="p">)</span> <span class="k">do</span>
          <span class="n">send</span> <span class="n">self</span><span class="p">(),</span> <span class="ss">:exit</span>
        <span class="k">end</span>
        <span class="n">loop</span><span class="p">(</span><span class="n">new_results</span><span class="p">,</span> <span class="n">results_expected</span><span class="p">)</span>
      <span class="ss">:exit</span> <span class="o">-&gt;</span>
        <span class="n">average</span> <span class="o">=</span> <span class="nc">Enum</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">results</span><span class="p">)</span> <span class="o">/</span> <span class="nc">Enum</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
        <span class="nc">IO</span><span class="o">.</span><span class="n">puts</span><span class="p">(</span><span class="s2">&quot;The average time was </span><span class="si">#{</span><span class="n">average</span><span class="si">}</span><span class="s2"> microseconds&quot;</span><span class="p">)</span>
      <span class="bp">_</span> <span class="o">-&gt;</span>
        <span class="n">loop</span><span class="p">(</span><span class="n">results</span><span class="p">,</span> <span class="n">results_expected</span><span class="p">)</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>This module just contains a <code>loop/2</code> function. Inside, we can see some similarities to the <code>loop/0</code>
funcion in <code>MathRacer.Adder</code>, with a few more possible messages defined. <code>loop/2</code>&lsquo;s arguments are a
list, which will be used to build up a list of all the results it receives, and a number
representing how many results it should expect to receive. Notice that the <code>loop/2</code> function is
recursive. Two of the message options end by calling the loop function again. This is because the
coordinator process has a different role than the adder processes. Each Adder process does
its calculation and returns, then exits. If you need to add again, you need to spawn another
process. The coordinator process, on the other hand, needs to hang around and wait for every adder&rsquo;s
result to come in. In order to accomplish this, it must call it self once it receives a message in
order to keep listening for the next one.</p>

<p>When the Coordinator receives a message from an Adder, it first prints a message to the console
informing you of the time it took that Adder to get its result. It then adds the new result to its
ongoing list of results and checks to see if its waiting on any more. If it is, the loop function
calls itself with the new list of results. If it has received all its expected messages, the
coordinator process actually sends itself a message, consisting of the atom <code>:exit</code>. Processes can
send themselves messages. This is useful for isolating unrelated logic instead of mixing concerns
into the same function. When the Coordinator receives an exit message, it takes its list of results,
calculates the average time, and prints that to the console and exits.</p>

<h2>send(self(), :wrap_it_up)</h2>

<p>So that&rsquo;s a (not so) brief overview of some of the basics of dealing with processes in Elixir.
There&rsquo;s a lot more to look at. We haven&rsquo;t covered linking or monitoring a process, which is how you
can have things like Supervisors and other awesome Elixir functionality. But I hope this got you
interested in digging more into how Elixir works under the hood and how it does the awesome things
it does.</p>
]]>
      </description>
      <pubDate>Mon, 17 Jun 2019 11:00:00 -0400</pubDate>
      <link>https://teamgaslight.com/blog/intro-to-processes-in-elixir</link>
      <guid>https://teamgaslight.com/blog/intro-to-processes-in-elixir</guid>
    </item>
    <item>
      <title>Creating Simple Layout Templates with CSS Grid</title>
      <author>Beau Heubach</author>
      <description>
        <![CDATA[<p>There is so much to love about CSS Grid and the various methods it provides for defining a layout. Of course, with great power comes sloppy front end code. It did not take me long to muck up a grid layout leaving my team members with a tangled mess of <code>grid-columns</code> and <code>grid-rows</code>.  </p>

<h2>Label Page Components with Template Areas</h2>

<p>Defining and rearranging template areas is one of the cleanest and straight-forward methods for creating template parts that can put together in different page layouts. Here is what a simple interchange grid would look like.</p>

<h2>Define The Grid</h2>

<p>First, we must define our grid lines. For this example, we will create three columns of equal width and three rows with a large center row.</p>
<div class="highlight"><pre><span></span><span class="nt">body</span> <span class="p">{</span>
  <span class="nt">display</span><span class="nd">:</span> <span class="nt">grid</span><span class="o">;</span>
  <span class="nt">grid-template-columns</span><span class="nd">:</span> <span class="nt">repeat</span><span class="o">(</span><span class="nt">3</span><span class="o">,</span> <span class="nt">1fr</span><span class="o">);</span>
  <span class="nt">grid-template-rows</span><span class="nd">:</span> <span class="nt">1fr</span> <span class="nt">minmax</span><span class="o">(</span><span class="nt">300px</span><span class="o">,</span> <span class="nt">65vh</span><span class="o">)</span> <span class="nt">1fr</span><span class="o">;</span>
<span class="p">}</span>
</pre></div>
<p><img src="https://gaslight-blog.s3.amazonaws.com/creating-simple-layout-templates-with-css-grid/grid-template-lines.png" alt=""></p>

<h2>Assign Your Template Areas</h2>

<p>Once you have the grid lines set, we’ll create classes for the containers that will represent the different sections of our grid, and then assign each one a <code>grid-area</code> title.  </p>
<div class="highlight"><pre><span></span><span class="nc">.header</span> <span class="p">{</span>
  <span class="nt">grid-area</span><span class="nd">:</span> <span class="nt">header</span><span class="o">;</span>
<span class="p">}</span>
<span class="nc">.main</span> <span class="p">{</span>
  <span class="nt">grid-area</span><span class="nd">:</span> <span class="nt">main</span><span class="o">;</span>
<span class="p">}</span>
<span class="nc">.list__col-1</span> <span class="p">{</span>
  <span class="nt">grid-area</span><span class="nd">:</span> <span class="nt">list-col-1</span><span class="o">;</span>
<span class="p">}</span>
<span class="nc">.list__col-2</span> <span class="p">{</span>
  <span class="nt">grid-area</span><span class="nd">:</span> <span class="nt">list-col-2</span><span class="o">;</span>
<span class="p">}</span>
<span class="nc">.list__co3-1</span> <span class="p">{</span>
  <span class="nt">grid-area</span><span class="nd">:</span> <span class="nt">list-col-3</span><span class="o">;</span>
<span class="p">}</span>
<span class="nc">.sidebar</span> <span class="p">{</span>
  <span class="nt">grid-area</span><span class="nd">:</span> <span class="nt">sidebar</span><span class="o">;</span>
<span class="p">}</span>
<span class="nc">.footer</span> <span class="p">{</span>
  <span class="nt">grid-area</span><span class="nd">:</span> <span class="nt">footer</span><span class="o">;</span>
<span class="o">]</span>
</pre></div>
<h2>Defining The Layout</h2>

<p>To define our base layout, we will be using the <code>grid-template-area</code> property. The names assigned to each container&rsquo;s <code>grid-area</code> can be laid out according to the defined columns and rows. When we add each row of template areas to a new line, the css becomes a visual pattern of our grid layout.</p>
<div class="highlight"><pre><span></span><span class="nt">body</span> <span class="p">{</span>
  <span class="nt">grid-template-areas</span><span class="nd">:</span> 
    <span class="s2">&quot;header header header&quot;</span>
    <span class="s2">&quot;main main sidebar&quot;</span>
    <span class="s2">&quot;footer footer footer&quot;</span><span class="o">;</span>
<span class="p">}</span>
</pre></div>
<p><img src="https://gaslight-blog.s3.amazonaws.com/creating-simple-layout-templates-with-css-grid/grid-template-one.png" alt=""></p>

<h2>Adapt The Layout for Different Template Types</h2>

<p>Now we can get creative by defining several layout variations for separate templates. For this example, we will create CSS for an article template with header or sidebar and an article list template.</p>
<div class="highlight"><pre><span></span><span class="nt">body</span><span class="nc">.template__article</span> <span class="p">{</span>
  <span class="nt">grid-template-areas</span><span class="nd">:</span> 
    <span class="s2">&quot;main main main&quot;</span>
    <span class="s2">&quot;main main main&quot;</span>
    <span class="s2">&quot;footer footer footer&quot;</span><span class="o">;</span>
<span class="p">}</span>
</pre></div>
<p><img src="https://gaslight-blog.s3.amazonaws.com/creating-simple-layout-templates-with-css-grid/grid-template-two.png" alt=""></p>
<div class="highlight"><pre><span></span><span class="nt">body</span><span class="nc">.template__list</span> <span class="p">{</span>
  <span class="nt">grid-template-areas</span><span class="nd">:</span> 
    <span class="s2">&quot;header header header &quot;</span>
    <span class="s2">&quot;list-col-1 list-col-2 list-col-3&quot;</span>
    <span class="s2">&quot;footer footer footer&quot;</span><span class="o">;</span>
<span class="p">}</span>
</pre></div>
<p><img src="https://gaslight-blog.s3.amazonaws.com/creating-simple-layout-templates-with-css-grid/grid-template-three.png" alt=""></p>

<p>Now that we can easily create different types of variety of defined layouts, we can now consider how is method will help solve another problem. With the rise of design systems, we are building consistent components that are pieced together to create larger components that fit together into pages. We’re no longer designing simple pages, so how do we incorporate this great page layout method into a design system process? </p>

<p>More on that another day&hellip;</p>
]]>
      </description>
      <pubDate>Thu, 06 Jun 2019 16:00:05 -0400</pubDate>
      <link>https://teamgaslight.com/blog/creating-simple-layout-templates-with-css-grid</link>
      <guid>https://teamgaslight.com/blog/creating-simple-layout-templates-with-css-grid</guid>
    </item>
    <item>
      <title>React Hooks at a Glance</title>
      <author>Dustin Kocher</author>
      <description>
        <![CDATA[<p>In this post we are going to answer the question why you would want to use React hooks and go over a few of the ones built in.  I will be covering the <code>useState</code> and <code>useEffect</code> hooks as I feel these will give you the most bang for your buck when trying to convert to functional components.</p>

<h2>Why Hooks?</h2>

<p>Why should you use hooks? What benefits do they provide?<br>
*  They give you the ability to connect and reuse stateful logic, removing the need for render props and higher-order components.
*  They help take the logic that is spread out among the many lifecycle methods of a complex component and relocate it into smaller independent functions. 
*  They reduce confusion on when or why you need a component to be a class versus a function.</p>

<h2>useState at a Glance</h2>

<p>The useState hook allows you to give state to a functional component - meaning you will no longer need to worry about making a class component if you want to have state in a functional component.  Let&rsquo;s look at a small example and explain what is going on.</p>
<div class="highlight"><pre><span></span><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">useState</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&quot;react&quot;</span><span class="p">;</span>
<span class="kr">import</span> <span class="nx">_</span> <span class="nx">from</span> <span class="s2">&quot;lodash&quot;</span><span class="p">;</span>

<span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Tasks</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
  <span class="kr">const</span> <span class="p">[</span><span class="nx">newTask</span><span class="p">,</span> <span class="nx">setNewTask</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">();</span>
  <span class="kr">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>

  <span class="kd">function</span> <span class="nx">addTask</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">setTasks</span><span class="p">([...</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">newTask</span><span class="p">]);</span>
    <span class="nx">setNewTask</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="p">(</span>
    <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
      <span class="o">&lt;</span><span class="nx">input</span>
        <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;text&quot;</span>
        <span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">newTask</span><span class="p">}</span>
        <span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="nx">e</span> <span class="p">=&gt;</span> <span class="nx">setNewTask</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">)}</span>
      <span class="o">/&gt;</span>
      <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{</span><span class="nx">addTask</span><span class="p">}</span><span class="o">&gt;</span><span class="nx">Add</span><span class="o">&lt;</span><span class="err">/button&gt;</span>
      <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
        <span class="p">{</span><span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">task</span> <span class="p">=&gt;</span> <span class="p">(</span>
          <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">task</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/div&gt;</span>
        <span class="p">))}</span>
      <span class="o">&lt;</span><span class="err">/div&gt;</span>
    <span class="o">&lt;</span><span class="err">/div&gt;</span>
  <span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>In this example we are making a task list. The user types in a task, clicks the Add button, and a task is added to the task list.  So what is going on with the react hook <code>useState</code>?</p>

<ul>
<li> Every time <code>useState()</code> is called two things are returned.  A new state variable and a function to update the state variable.  As you can see <code>const [newTask, setNewTask] = useState()</code> creates a new state variable and using array deconstruction we call the new state variable <code>newTask</code> and the function to update this variable <code>setNewTask</code> </li>
<li> You can give a state variable an initial value by passing in an argument to <code>useState</code>.  On the following line we give the state variable <code>tasks</code> an initial value of an empty array, <code>const [tasks, setTasks] = useState([])</code>.  Here it is an array but it can be anything, a string, integer, or an object.</li>
<li> To use or display the state variables all you need to do is call the state variables <code>tasks</code> or <code>newTask</code> directly.</li>
<li> To update a state variable let&rsquo;s look at the <code>addTask()</code> function.  Inside this function you can see we are updating both the <code>tasks</code> state variable and <code>newTasks</code> state variable.  In both examples you can see we just pass in a new value to the update function and react will re-render the component with the new value. One thing to point out is you will want to follow the same rules you always have of not mutating the state variable directly but recreating it and adding to it.  As you can see in <code>setTasks([...tasks, newTask])</code> we create a new array by deconstructing the <code>tasks</code> state variable and append the <code>newTask</code> state variable to the end.</li>
</ul>

<h2>useEffect at a Glance</h2>

<p>The <code>useEffect</code> hook combines several of the most commonly used lifecycle hooks (<code>componentDidMount</code>, <code>componentDidUpdate</code>, and <code>componentWillUnmount</code>) used in classes into one central API. Now let&rsquo;s add on to the previous example a <code>useEffect</code> hook:</p>
<div class="highlight"><pre><span></span><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">useState</span><span class="p">,</span> <span class="nx">useEffect</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&quot;react&quot;</span><span class="p">;</span>
<span class="kr">import</span> <span class="nx">_</span> <span class="nx">from</span> <span class="s2">&quot;lodash&quot;</span><span class="p">;</span>
<span class="kr">import</span> <span class="nx">axios</span> <span class="nx">from</span> <span class="s2">&quot;axios&quot;</span><span class="p">;</span>

<span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Tasks</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
  <span class="kr">const</span> <span class="p">[</span><span class="nx">newTask</span><span class="p">,</span> <span class="nx">setNewTask</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">();</span>
  <span class="kr">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>

  <span class="nx">useEffect</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
    <span class="nx">axios</span><span class="p">({</span>
      <span class="nx">method</span><span class="o">:</span> <span class="s2">&quot;get&quot;</span><span class="p">,</span>
      <span class="nx">url</span><span class="o">:</span> <span class="s2">&quot;https://api.jsonbin.io/b/5c6af0c09dfbb91d718215d8&quot;</span><span class="p">,</span>
      <span class="nx">params</span><span class="o">:</span> <span class="p">{}</span>
    <span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="nx">response</span> <span class="p">=&gt;</span> <span class="p">{</span>
      <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">tasks</span><span class="p">);</span>
    <span class="p">});</span>

    <span class="cm">/*return function cleanup() {</span>
<span class="cm">      //put cleanup logic here</span>
<span class="cm">    }*/</span>
  <span class="p">},</span> <span class="p">[]);</span>

  <span class="p">...</span>

<span class="p">}</span>
</pre></div>
<p>This uses the <code>axios</code> package to asynchronously fetch tasks and then set the state variable <code>tasks</code> to the returned list of tasks.  So what should you be looking at in the <code>useEffect</code> hook?</p>

<ul>
<li> The first thing to notice is that <code>useEffect</code> is called inside of the component.  This gives it access to everything that is declared in the component including the state variables created by the <code>useState</code> hook or any other variables generated from hooks such as <code>useReducer</code> or <code>useContext</code>. To be clear, you will not have the ability to call any of these hooks directly in <code>useEffect</code>.  For example you can&rsquo;t do <code>const [var, func] = useState()</code> inside of the <code>useEffect</code> hook.  You can only call hooks directly inside the function component.</li>
<li> <code>useEffect</code> takes two arguments: a function and an array. </li>
<li> The function is what will be called when the <code>useEffect</code> hook is called. Here we are calling out to an API endpoint to retrieve a list of tasks.  As you see commented out you can return a function to perform cleanup logic.  This is great if for example you are dealing with pub/sub connections and you need to clean up those connections. </li>
<li> The second is an optional parameter which is an array.  This tells the <code>useEffect</code> hook when it should be called.  If nothing is passed in here the <code>useEffect</code> hook will be called on every render.  Passing in an empty array will only run this hook on mount and unmount.  Passing in an array with the state variable, for example <code>tasks</code>, will call the hook every time it is updated.<br></li>
<li> You can have as many <code>useEffect</code> hooks in a component as needed.  Ideally you should create one for each set of related pieces of logic that you need.  For example I would create a new <code>useEffect</code> in the scenario were I wanted to update the API endpoint every time <code>tasks</code> is updated.</li>
</ul>

<h2>Conclusion</h2>

<p>React has done a lot through the years to improve itself.  I hope this gives you some insight into how to use hooks and the value they bring.  I personally feel on top of the benefits previously mentioned, this will help in making code easier to read but also the logic of a component and its lifecycles easier to follow.</p>
]]>
      </description>
      <pubDate>Mon, 20 May 2019 08:21:30 -0400</pubDate>
      <link>https://teamgaslight.com/blog/react-hooks-at-a-glance</link>
      <guid>https://teamgaslight.com/blog/react-hooks-at-a-glance</guid>
    </item>
    <item>
      <title>Vertical Rhythm on the Web</title>
      <author>Katie Pohlman</author>
      <description>
        <![CDATA[<p>Grids are a thing. They’ve been a thing. There’s nothing earth-shattering about designing on a grid. In fact, it’s so commonplace that there are, what feels like, an infinite number of tools available to make it easier to design on a grid—<a href="https://getbootstrap.com/" target="_blank">Bootstrap</a>, <a href="https://foundation.zurb.com/" target="_blank">Foundation</a>, <a href="https://bulma.io/" target="_blank">Bulma</a>, among others. But there’s one thing these tools all have in common, and it’s what they’re missing. Verticality. (Is that even a word?)</p>

<p>Ever come across a site that is laid out beautifully across all screen sizes? It responds as you narrow or widen your window, the sidebar wraps effortlessly as real estate becomes sparse, the gutter spacing between elements is consistent; it’s glorious. But then you start to scroll. There’s weird white space between the header and main content, the footer feels like it’s falling off the page, content starts to run together and hierarchy is lost. That’s what I’m talking about. It is so easy to create and maintain these horizontal grids, but the structure is lost as you move down the page — but it doesn’t have to be!</p>

<p>I’ve long envied the blog post that showcases a site falling effortlessly into a vertical grid. It’s always been this thing that I aspired to do, so I decided to finally demystify it. And, thankfully, it’s really not too complicated.</p>

<h3>Establishing the grid</h3>

<p>First things first, we have to decide on and set up the vertical rhythm on the page. So, where to begin? What is a vertical unit we already have in our arsenal? Line height. Every site has content; all content has a line-height—Let’s go with that!</p>

<p>Let’s assume our site has a base font-size: 20px; and a line-height: 30px; </p>
<div class="highlight"><pre><span></span><span class="nt">html</span><span class="o">,</span> <span class="nt">body</span> <span class="p">{</span>

<span class="k">font-size</span><span class="p">:</span> <span class="mi">20</span><span class="kt">px</span><span class="p">;</span>

    <span class="k">line-height</span><span class="p">:</span> <span class="mi">30</span><span class="kt">px</span><span class="p">;</span>

<span class="p">}</span>
</pre></div>
<p>If our base line-height is 30px, then we should run with a 30px vertical grid. But what does that mean? That means that we need to use 30px as a base unit for spacing throughout the site; everything should be in multiples of 30px. And voilà — we’ve got a vertical grid.</p>

<p>Want some space between those consecutive <code>.form</code> elements?</p>
<div class="highlight"><pre><span></span><span class="p">.</span><span class="nc">form</span> <span class="o">+</span> <span class="p">.</span><span class="nc">form</span> <span class="p">{</span>

<span class="k">margin-top</span><span class="p">:</span> <span class="mi">90</span><span class="kt">px</span><span class="p">;</span>

<span class="p">}</span>
</pre></div>
<p>Need some breathing room inside that <code>.sidenav</code>?</p>
<div class="highlight"><pre><span></span><span class="p">.</span><span class="nc">sidenav</span> <span class="p">{</span>

<span class="k">padding</span><span class="p">:</span> <span class="mi">30</span><span class="kt">px</span><span class="p">;</span>

<span class="p">}</span>
</pre></div>
<p>Your <code>&lt;h1&gt;</code> not fit inside those 30px?</p>
<div class="highlight"><pre><span></span><span class="nt">h1</span> <span class="p">{</span>

<span class="k">font-size</span><span class="p">:</span> <span class="mi">50</span><span class="kt">px</span><span class="p">;</span>

<span class="k">line-height</span><span class="p">:</span> <span class="mi">60</span><span class="kt">px</span><span class="p">;</span>

<span class="p">}</span>
</pre></div>
<h3>Where is gets tricky</h3>

<p>Great! It’s that simple: set a base line-height, then just use multiples of it for everything in your system. But there are some snags we need to address before this can work entirely. </p>

<h4>Browsers like to add in their own default declarations.</h4>

<p>We need to strip the browser of its default spacing. This means the sizing, padding and margins on the body, h-tags, lists, links, etc. so that we’re starting from the ground up. We want to strip everything away so that we can build it back up again onto our grid. So, in our base styles, let’s add</p>
<div class="highlight"><pre><span></span><span class="nt">html</span><span class="o">,</span> <span class="nt">body</span> <span class="p">{</span>

<span class="k">margin</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span>

<span class="k">padding</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span>

<span class="p">}</span>




<span class="o">*</span> <span class="p">{</span>

<span class="k">line-height</span><span class="p">:</span> <span class="mi">30</span><span class="kt">px</span><span class="p">;</span>

<span class="p">}</span>




<span class="nt">h1</span><span class="o">,</span> <span class="nt">h2</span><span class="o">,</span> <span class="nt">h3</span><span class="o">,</span> <span class="nt">h4</span><span class="o">,</span> <span class="nt">h5</span><span class="o">,</span> <span class="nt">h6</span><span class="o">,</span> <span class="nt">ol</span><span class="o">,</span> <span class="nt">ul</span><span class="o">,</span> <span class="nt">blockquote</span><span class="o">,</span> <span class="nt">p</span> <span class="p">{</span>

<span class="k">margin</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span>

<span class="p">}</span>
</pre></div>
<h4>Scalability &amp; Maintainability</h4>

<p>Cool, cool, cool. That’s great and all, but what if I want to change my grid after I’ve spent some time with it?  <a href="https://sass-lang.com/" target="_blank">Sass</a> to the rescue!</p>

<p>To set up a more maintainable and responsive vertical grid, we’ll want to use the power of Sass variables and functions to our advantage. Thankfully, it’s not too complicated. We just need three variables and one function and we’re off to the races.</p>

<h5>Variables</h5>
<div class="highlight"><pre><span></span><span class="o">$</span><span class="nt">font-size-base</span><span class="o">:</span> <span class="nt">20px</span><span class="o">;</span>

<span class="o">$</span><span class="nt">line-height-base</span><span class="o">:</span> <span class="nt">1</span><span class="p">.</span><span class="nc">5</span><span class="o">;</span>

<span class="o">$</span><span class="nt">grid</span><span class="o">:</span> <span class="o">$</span><span class="nt">font-size-base</span> <span class="o">*</span> <span class="o">$</span><span class="nt">line-height-base</span><span class="o">;</span>
</pre></div>
<h5>Function</h5>
<div class="highlight"><pre><span></span><span class="x">@function grid($count) </span><span class="cp">{</span>

  <span class="o">@</span><span class="na">return</span> <span class="na">calc</span><span class="o">(</span><span class="err">#</span><span class="cp">{</span><span class="nv">$grid</span><span class="cp">}</span> <span class="o">*</span> <span class="err">#</span><span class="cp">{</span><span class="nv">$count</span><span class="cp">}</span><span class="o">);</span>

<span class="cp">}</span><span class="x"></span>
</pre></div>
<p>Where <code>$count</code> is the multiple of grid lines we want to use. So, calling <code>grid(1)</code> would return 30px, <code>grid(2)</code> would return 60px, etc. This allows us to declare grid lines without hard-coding any values.</p>

<p>So, our grid setup would look something like</p>
<div class="highlight"><pre><span></span><span class="nt">html</span><span class="o">,</span> <span class="nt">body</span> <span class="p">{</span>

<span class="k">font-size</span><span class="p">:</span> <span class="err">$</span><span class="k">font-size</span><span class="o">-</span><span class="n">base</span><span class="p">;</span>

<span class="k">line-height</span><span class="p">:</span> <span class="err">$</span><span class="nf">grid</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

<span class="p">}</span>




<span class="o">*</span> <span class="p">{</span>

<span class="k">line-height</span><span class="p">:</span> <span class="nf">grid</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

<span class="p">}</span>
</pre></div>
<p>And using the grid would look something like</p>
<div class="highlight"><pre><span></span><span class="p">.</span><span class="nc">form</span> <span class="o">+</span> <span class="p">.</span><span class="nc">form</span> <span class="p">{</span>

<span class="k">margin-top</span><span class="p">:</span> <span class="nf">grid</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>

<span class="p">}</span>




<span class="p">.</span><span class="nc">sidenav</span> <span class="p">{</span>

<span class="k">line-height</span><span class="p">:</span> <span class="nf">grid</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

<span class="k">padding</span><span class="p">:</span> <span class="nf">grid</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

<span class="p">}</span>




<span class="nt">h1</span> <span class="p">{</span>

<span class="k">font-size</span><span class="p">:</span> <span class="mf">2.5</span><span class="kt">em</span><span class="p">;</span>

<span class="k">line-height</span><span class="p">:</span> <span class="nf">grid</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

<span class="p">}</span>
</pre></div>
<h4>Aaand we’re done!</h4>

<p>Tada! That’s how you set up and maintain a vertical grid. It’s just a few lines of code and a lifetime of happiness. Okay, maybe that’s an overstatement, but I love when I learn that something seemingly complicated is actually really simple. It’s a beautiful, beautiful thing. </p>

<p>Want to try if for yourself? Play with this <a href="https://codepen.io/5fe5840f-0f33-4df0-9a71-e3bfbb4ce5bd/pen/MLMqpb">Codepen</a>!</p>
]]>
      </description>
      <pubDate>Mon, 06 May 2019 14:12:26 -0400</pubDate>
      <link>https://teamgaslight.com/blog/vertical-rhythm-on-the-web</link>
      <guid>https://teamgaslight.com/blog/vertical-rhythm-on-the-web</guid>
    </item>
    <item>
      <title>Is Custom Software Worth the Investment? </title>
      <author>Steve Hennegan</author>
      <description>
        <![CDATA[<p>So you want to know how much custom software costs? Here’s the thing … custom software is equally challenging, complex, and exciting. Like anything custom, it can be difficult to put a price on. At Gaslight, we typically incorporate the following in our sales process; curiosity, listening, collaboration, white board scribbling, practical thinking and coffee - to name a few. Software is daunting enough - we want the sales piece to have minimal stress and be educational for everyone that we interact with. Let’s break down some expectations in the sales process and explain why custom software is indeed, worth the investment. </p>

<p>Initially, we just want to get to know you - your motivations, the things that make your shoulders raise with a quick breath of excitement. We’ll ask how we can help you accomplish your professional and  personal goals. We aim to make you comfortable to sit back and talk about things outside of the project. This allows us to grab a better understanding of the person you are, and envision the team that would align with your personality. If the feeling is mutual, we’ll move on to the three phases of scoping work. </p>

<p><strong>Business scoping</strong> tells us about your organization. What makes you unique, what you identify as a challenge, who your competitors are, and areas for improvement.  Brag about your vision, your 1, 5 and 10 year plan for the business. Flaunt your people, the culture, and the story of how you got to where you are today. We want to understand your roles &amp; responsibilities, who supports who, the reporting structure, and how can we make you even more of a crowd favorite in your marketplace. </p>

<p><strong>Technical scoping</strong> - now the ball is rolling and we’re all kinds of excited. This is where sales takes a step back and let the pros do the talking. We’ll bring in a technical resource from our team during this stage who embodies confidence and complexity in that space. Empathy &amp; Story Mapping wraps up this phase. The goal with this exercise is to understand how to make your idea come to life through technology - and oftentimes, this is the most challenging step. We are never going to tell you that building custom software is easy, but we will assure you that it’s worth it. </p>

<p>And as you’ve been ramping up ideas and anxiously waiting at the same time, <strong>project scoping</strong> brings us home. But here is where we are different - we’ll build the scope of work with you in the room and that provides financial clarity. It may be a first draft, but we want you to tell us what we should be building. It’s important to be open about pricing and aligned on goals and timelines.  </p>

<p>A traditional Gaslight project typically lasts for six to eight months and costs anywhere from 300,000 to 500,000 dollars. But we welcome non-traditional just as often. If we communicate effectively throughout the process the final step is more of a formality. This final step brings us to some signatures and we roll right into kick off meeting plans, we’re off to the races. Let’s build something amazing, and let’s build it together! </p>

<p>To learn more about what we’re capable of … visit our <a href="https://teamgaslight.com/services">services</a> page or set some time for <a href="https://teamgaslight.com/coffee">coffee</a> with us. </p>
]]>
      </description>
      <pubDate>Mon, 22 Apr 2019 11:32:53 -0400</pubDate>
      <link>https://teamgaslight.com/blog/is-custom-software-worth-the-investment</link>
      <guid>https://teamgaslight.com/blog/is-custom-software-worth-the-investment</guid>
    </item>
    <item>
      <title>Refactoring Patterns in Elixir: Replace Conditional with Pattern Matching</title>
      <author>Zack Kayser</author>
      <description>
        <![CDATA[<h2>Part 1: Replace Conditionals with Pattern Matching</h2>

<p><em>Replace Complex Conditionals in Function Bodies with Pattern Matching in Function Heads</em></p>

<p>Several of us developers at Gaslight have been meeting up on Fridays to discuss Martin Fowler&rsquo;s seminal book, <a href="https://martinfowler.com/books/refactoring.html">Refactoring</a>. The 2nd edition of his book, which is what we have been focused on, features examples written in JavaScript. The 1st edition, released in 2000, contained examples in Java. </p>

<p>The first day we got together to discuss the book, an interesting question was raised: How do language paradigms and specific language implementations affect the way developers tackle the task of refactoring? For example, in cases where you might reach for a tool like inheritance in object-oriented languages, what would your alternative be if you were working in a functional language like Elixir or Erlang where tools such as inheritance are unavailable? On the flip side, if you were going to reach for a tool like pattern matching in Elixir, what would you reach for if you were coding in, say, Ruby? </p>

<p>Since many of us here at Gaslight share a passion for Elixir, we started discussing if there was a set of &ldquo;refactoring patterns&rdquo; that we find ourselves coming back to when working on Elixir projects. It soon became obvious that there are plenty of techniques when it comes to refactoring Elixir, and we thought it would be great to put some of those down in writing and share them with the community.</p>

<p>Now, without any further ado, let&rsquo;s jump into our first refactoring pattern in Elixir:</p>

<h3>Replace Conditional with Function Head Pattern Matching</h3>

<p>Our first pattern is a spin on one of the more influential refactoring techniques Martin Fowler brings up in his book: &ldquo;Replace Conditional with Polymorphism&rdquo;. While this pattern does not, perhaps, fulfill what we might traditionally think of as polymorphism, it is a great option for refactoring complex conditionals in function bodies. We will also share another approach to refactoring conditionals using Elixir protocols &ndash; an approach that gives you polymorphism on data structures &ndash; in a future post. </p>

<p>To demonstrate how this pattern looks, let&rsquo;s take a look at an example from <em>Refactoring</em> ported over to Elixir:</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">Bird</span> <span class="k">do</span>

  <span class="kd">defstruct</span> <span class="ss">type</span><span class="p">:</span> <span class="no">nil</span><span class="p">,</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="ss">voltage</span><span class="p">:</span> <span class="mi">0</span>

  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="n">bird</span><span class="p">)</span> <span class="k">do</span>
    <span class="k">case</span> <span class="n">bird</span><span class="o">.</span><span class="n">type</span> <span class="k">do</span>
      <span class="s2">&quot;EuropeanSwallow&quot;</span> <span class="o">-&gt;</span>
        <span class="s2">&quot;average&quot;</span>
      <span class="s2">&quot;AfricanSwallow&quot;</span> <span class="o">-&gt;</span>
        <span class="k">if</span> <span class="n">bird</span><span class="o">.</span><span class="n">number_of_coconuts</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="k">do</span>
          <span class="s2">&quot;tired&quot;</span>
        <span class="k">else</span>
          <span class="s2">&quot;average&quot;</span>
        <span class="k">end</span>
      <span class="s2">&quot;NorwegianParrot&quot;</span> <span class="o">-&gt;</span>
        <span class="k">if</span> <span class="n">bird</span><span class="o">.</span><span class="n">voltage</span> <span class="o">&gt;</span> <span class="mi">100</span> <span class="k">do</span>
          <span class="s2">&quot;scorched&quot;</span>
        <span class="k">else</span>
          <span class="s2">&quot;beautiful&quot;</span>
        <span class="k">end</span>
      <span class="bp">_</span> <span class="o">-&gt;</span>
        <span class="s2">&quot;average&quot;</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>The example here is pretty straightforward: we pass in a <code>Bird</code> struct to the <code>plumage/1</code> function and pattern match on the type of bird in a case statement. Given the size of this function and its simplicity, it does not immediately jump out as being in dire need of refactoring, but there are a few &ldquo;smells&rdquo; that stick out if you have been working with Elixir for a while:</p>

<ol>
<li>We are pattern matching on strings in the case statement. If new requirements come in that would force us to add more clauses to this case statement, this approach can get unwieldy in no time. </li>
<li>We are using nested <code>if</code> blocks inside of matches in our case statement.</li>
<li>In the case of the <code>EuropeanSwallow</code> and the <code>AfricanSwallow</code> with less than 2 coconuts, we can just fall back to the default value of <code>average</code>. This would allow us to remove the &ldquo;EuropeanSwallow&rdquo; clause from the statement altogether, but we would still need to address the extra conditional for the <code>AfricanSwallow</code>.</li>
</ol>

<p>So what are some solutions to clean this up a bit and make it easier to work with? <em>Let&rsquo;s extract the case statement conditional to pattern matching in function heads</em>:</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">Bird</span> <span class="k">do</span>
  <span class="kd">defstruct</span> <span class="ss">type</span><span class="p">:</span> <span class="no">nil</span><span class="p">,</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="ss">voltage</span><span class="p">:</span> <span class="mi">0</span>

  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{</span><span class="ss">type</span><span class="p">:</span> <span class="s2">&quot;AfricanSwallow&quot;</span><span class="p">,</span> <span class="ss">number_of_coconuts</span><span class="p">:</span> <span class="n">num</span><span class="p">})</span> <span class="ow">when</span> <span class="n">num</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">,</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;tired&quot;</span>

  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{</span><span class="ss">type</span><span class="p">:</span> <span class="s2">&quot;NorwegianParrot&quot;</span><span class="p">,</span> <span class="ss">voltage</span><span class="p">:</span> <span class="n">voltage</span><span class="p">})</span> <span class="ow">when</span> <span class="n">voltage</span> <span class="o">&gt;</span> <span class="mi">100</span><span class="p">,</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;scorched&quot;</span>

  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{</span><span class="ss">type</span><span class="p">:</span> <span class="s2">&quot;NorwegianParrot&quot;</span><span class="p">}),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;beautiful&quot;</span>

  <span class="kd">def</span> <span class="n">plumage</span><span class="p">(</span><span class="err">%</span><span class="bp">__MODULE__</span><span class="p">{}),</span> <span class="ss">do</span><span class="p">:</span> <span class="s2">&quot;average&quot;</span>
<span class="k">end</span>
</pre></div>
<p>Since Elixir and Erlang let you define multiple function heads for functions with the same arity, we can rely on pattern matching on our arguments and move more specific, conditional cases towards the top, leaving default and generic cases as the last definition(s) for a given function head. </p>

<p>The use of guard statements in the function heads allows us to remove the two nested <code>if</code> blocks from the original case statement: we extract the data needed to determine whether or not a condition has been met using pattern matching while ignoring data that is irrelevant for our calculation. For instance, we only need to know how many coconuts the <code>AfricanSwallow</code> has to determine whether it&rsquo;s plumage is <code>tired</code> or <code>average</code>, so we can ignore the <code>voltage</code> property altogether.</p>

<p>The combination of pattern matching in our function heads along with guard clauses allows us to capture any <code>Bird</code> that doesn&rsquo;t match our conditional logic or any of our top function heads with a default case: <code>def plumage(%__MODULE__{}), do: &quot;average&quot;</code>. </p>

<h3>When Should We Use <code>Replace Conditional with Function Head Pattern Matching</code>?</h3>

<p>This pattern is a great approach for cleaning up <code>if/else</code> blocks and nested conditionals inside of function bodies. It also works well if all you are doing inside of a function body is running a case statement on a single property of a data structure, as is the case in our example above. </p>

<h3>What Are Some Gotchas With This Pattern?</h3>

<p>Elixir&rsquo;s pattern matching is a super powerful tool that gets used a lot, and rightfully so. It can make your code more declarative and easier to reason about, but you certainly <em>can</em> get too carried away with it, and many Elixir/Erlang developers have probably been bitten by <em>overuse</em> of pattern matching before.</p>

<p>To illustrate this point, imagine based on the example given above that we had a requirement to calculate a wide variety of plumages for <em>every single species of bird in existence on the planet</em>! Further complicating things, each species of bird has different attributes that determine their plumage. If you attempted to codify that using pattern matching in function heads in your <code>Bird</code> module, you would be in the fastlane on a one-way street to &ldquo;What even in the world is going on here?!&rdquo; </p>

<p>Granted, the example I just gave is an argument ad absurdum, but I find that there is generally an upper limit on how many function heads you can match on before your code actually starts becoming <em>more difficult</em> to read and understand. While I can&rsquo;t provide any specific advice on what that upper limit might be, I generally use this as a simple rule of thumb: If all of the function heads we are concerned with fit on the screen all at once, then our approach to pattern matching should work fine and the code will be easy to reason about. As we add more and more function heads, it becomes increasingly harder to reason about the code and thus less and less effective. In cases where this approach becomes unwieldy, you might want to try breaking out different data structures and having a protocol that has implementations for all of the data structures you need.</p>

<p>We will have a post coming up in the future that does just that: <code>Replace Conditional with Polymorphism: Elixir Protocols</code>. </p>

<p>Thank you for reading and happy refactoring!</p>
]]>
      </description>
      <pubDate>Mon, 15 Apr 2019 09:58:18 -0400</pubDate>
      <link>https://teamgaslight.com/blog/refactoring-patterns-in-elixir-replace-conditional-with-pattern-matching</link>
      <guid>https://teamgaslight.com/blog/refactoring-patterns-in-elixir-replace-conditional-with-pattern-matching</guid>
    </item>
    <item>
      <title>So You’re Building an Application With No Designer? Here's 3 Ways to Know the Usability is Suffering</title>
      <author>Beau Heubach</author>
      <description>
        <![CDATA[<p>Not long ago, my fellow designer Haley wrote an excellent blog post, “<a href="https://teamgaslight.com/blog/design-happens-whether-or-not-you-value-it-ignoring-it-can-ruin-your-project">Design happens whether or not you value it - ignoring it can ruin your project</a>”. She laid out a good explanation of what design is and argued why it matters. But understanding the importance of design within an application is just the first step in improving it.</p>

<h2>Poor UX has Consequences</h2>

<p>Identifying what is wrong or missing in an application can be challenging.  And if you’re not intentional about your user’s experiences, then the UX might be costing you more than you realize.  It can affect your goal conversions and user efficiency. You know&hellip;stuff that affects the purpose of having a website or application in the first place.</p>

<p>So maybe you are not able or not ready to bring a designer onto your project. Here are three problems to be aware of, and could indicate you have several more ..</p>

<h2>Usability Problems to look for:</h2>

<h3>Visual Hierarchy</h3>

<p>My former art director would always quote Incredibles, “When everybody is super, no one is!” This also applies to the content and components in your application. There is nothing more deadly to a layout than the poor visual hierarchy. Users will not know what to look at, no clear path to navigate the content, and the calls to action will be drowned out by everything else.</p>

<p><img src="https://gaslight-blog.s3.amazonaws.com/so-youre-building-an-application-with-no-designer-heres-3-ways-to-know-the-usability-is-suffering/hierarchy.jpg" alt="Examples of Visual Hierarchy"></p>

<h4>Signs of poor visual hierarchy:</h4>

<ul>
<li>Do your <h> tags clearly scale down in size, color, and weight?</li>
<li>Is there very little white/negative space? Do your page elements butt up against the edges of the page and/or next to each other?</li>
<li>Can you not tell what elements are clickable?</li>
<li>Can you not tell what content is the most important?</li>
<li>Can you not find the navigation in under 5 seconds?</li>
</ul>

<h3>Inconsistency</h3>

<p>This is usually an easy problem to recognize. Elements or components that share the same functionality, but look or act completely different only confuse your user. I know this sounds crazy, but when a user sees an element that looks different from other elements, they inherently expect it to act differently. A simple design inventory of a type of component, like a button, will quickly reveal how consistent your application is. If they vary in color, size, shape, and in how they interact, then you have a usability problem.</p>

<p><img src="https://gaslight-blog.s3.amazonaws.com/so-youre-building-an-application-with-no-designer-heres-3-ways-to-know-the-usability-is-suffering/consistancy.jpg" alt="Examples of Consistent UX"></p>

<h4>Signs of inconsistency:</h4>

<ul>
<li>Compare elements that do the same thing. Do they not look and act the same way?</li>
<li>Do your animations not have the same timing and feel?</li>
<li>Do you use different copy to direct the user to the same action?</li>
</ul>

<h3>Accessibility</h3>

<p>Accessibility is such an important part of what we do. It is so often overlooked because we typically browse our own application the same way every day. Unless you personally know every possible user of your application, chances are you have of users with different needs.</p>

<h4>Signs of poor accessibility:</h4>

<ul>
<li>Do you not have alt tags on all your images?</li>
<li>Use a color blind app to view you app, like <a href="https://itunes.apple.com/us/app/chromatic-vision-simulator/id389310222?mt=8">Chromatic Vision Simulator</a>. Do any of the colors blend together?</li>
<li>Does your content not make sense when using a screen reader on your page?</li>
</ul>

<h2>Can you guess the next step?</h2>

<p>There are many more issues that can arise from the lack of attention to design details on a project. If you found one of the problems above, chances are there are a few more. I think you know what I am going to say next. These problems are fixable with the help of a trained designer. And we may know a company with a few experienced designers who can help you out&hellip;</p>
]]>
      </description>
      <pubDate>Mon, 01 Apr 2019 08:15:29 -0400</pubDate>
      <link>https://teamgaslight.com/blog/so-youre-building-an-application-with-no-designer-heres-3-ways-to-know-the-usability-is-suffering</link>
      <guid>https://teamgaslight.com/blog/so-youre-building-an-application-with-no-designer-heres-3-ways-to-know-the-usability-is-suffering</guid>
    </item>
    <item>
      <title>Two-Factor Authentication in Elixir and Phoenix</title>
      <author>Cam Carter</author>
      <description>
        <![CDATA[<h1>Two-Factor Authentication in Elixir and Phoenix</h1>

<p>Multi-factor authentication relies on the user having two or more pieces of evidence (or factors) in order to gain access into a system. In this example we will implement a two-factor authentication system that requires the user to present two forms of evidence: what the user and only that user knows, their password, and a one time password sent to what only the user has access to, their email.</p>

<h3>A Disclaimer</h3>

<p>Now I&rsquo;m just going to assume that if you&rsquo;re reading this you&rsquo;ve already got the first factor of two-factor authentication figured out on your own. If that&rsquo;s not the case you can take a dive into the source code of the <a href="https://github.com/cam-carter/two-factor-auth-phx">example application</a> that already implements basic user authentication with <a href="https://github.com/ueberauth/guardian">Guardian</a> and <a href="https://github.com/riverrun/comeonin">comeonin</a>.</p>

<p>And if you figure out a better way of doing this (there&rsquo;s always a better way), then please feel free to email me your suggestions, insults, or compliments.</p>

<h3>Oh, and app dependencies</h3>

<p>Here&rsquo;s the list of dependencies I&rsquo;m using. You can just throw this in your <code>mix.exs</code> file.</p>
<div class="highlight"><pre><span></span><span class="kd">defp</span> <span class="n">deps</span> <span class="k">do</span>
  <span class="p">[</span>
    <span class="p">{</span><span class="ss">:bamboo</span><span class="p">,</span> <span class="s2">&quot;~&gt; 1.0&quot;</span><span class="p">},</span>
    <span class="p">{</span><span class="ss">:guardian</span><span class="p">,</span> <span class="s2">&quot;~&gt; 1.1&quot;</span><span class="p">},</span>
    <span class="p">{</span><span class="ss">:pot</span><span class="p">,</span> <span class="s2">&quot;~&gt; 0.9.6&quot;</span><span class="p">}</span>
  <span class="p">]</span>
<span class="k">end</span>
</pre></div>
<h2>HMAC one time password generation</h2>

<p>To generate this one time password, we will be using an Erlang library called <a href="https://github.com/yuce/pot">pot</a>. The function we will be using generates an HOTP, a one time password based on HMAC (hash-based message authentication code).</p>
<div class="highlight"><pre><span></span><span class="c1"># the secret token we&#39;ll need to generate the hotp</span>
<span class="c1"># this will need to stay hidden from the user</span>
<span class="n">token</span> <span class="o">=</span>
  <span class="ss">:crypto</span><span class="o">.</span><span class="n">strong_rand_bytes</span>
  <span class="o">|&gt;</span> <span class="nc">Base</span><span class="o">.</span><span class="n">encode32</span><span class="p">()</span>

<span class="c1"># the one_time_pass we&#39;ll send to our user&#39;s email</span>
<span class="n">one_time_pass</span> <span class="o">=</span> <span class="ss">:pot</span><span class="o">.</span><span class="n">hotp</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">_number_of_trials</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
<p>This code is going to come in handy later, so we&rsquo;ll want to hold on to it. We&rsquo;re creating a token with the <a href="http://erlang.org/doc/search/?q=crypto&x=0&y=0"><code>:crypto</code></a> application which is a module that provides access to cryptographic functions in Erlang. Then we&rsquo;re using that token to generate a one time password that can only be used&hellip; You, guessed it: once.</p>

<h2>Add a flag to the User? Add a flag to the User.</h2>

<p>To get things poppin&rsquo; off we&rsquo;re going to want to add a boolean flag to our <code>User</code> schema module and <code>:users</code> tabel. We can do that by generating a new Ecto migration.</p>
<div class="highlight"><pre><span></span>mix ecto.gen.migration add_has_2fa_to_users
</pre></div>
<p>Then we&rsquo;ll add the stuff to the other stuff&hellip;</p>
<div class="highlight"><pre><span></span><span class="c1">### whatevertimestamp_add_has_2fa_to_users.exs ###</span>

<span class="kd">def</span> <span class="n">change</span> <span class="k">do</span>
  <span class="n">alter</span> <span class="n">table</span><span class="p">(</span><span class="ss">:users</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">add</span><span class="p">(</span><span class="ss">:has_2fa</span><span class="p">,</span> <span class="ss">:boolean</span><span class="p">,</span> <span class="ss">default</span><span class="p">:</span> <span class="no">true</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>


<span class="c1">### user.ex ###</span>

<span class="n">schema</span> <span class="s2">&quot;users&quot;</span> <span class="k">do</span>
  <span class="n">field</span><span class="p">(</span><span class="ss">:email</span><span class="p">,</span> <span class="ss">:string</span><span class="p">)</span>
  <span class="n">field</span><span class="p">(</span><span class="ss">:has_2fa</span><span class="p">,</span> <span class="ss">:boolean</span><span class="p">,</span> <span class="ss">default</span><span class="p">:</span> <span class="no">false</span><span class="p">)</span> <span class="c1"># &lt;- the new stuff</span>
  <span class="n">field</span><span class="p">(</span><span class="ss">:password_hash</span><span class="p">,</span> <span class="ss">:string</span><span class="p">)</span>
  <span class="n">field</span><span class="p">(</span><span class="ss">:password</span><span class="p">,</span> <span class="ss">:string</span><span class="p">,</span> <span class="ss">virtual</span><span class="p">:</span> <span class="no">true</span><span class="p">)</span>
<span class="k">end</span>
</pre></div>
<p>Then we&rsquo;ll run our new, fancy migration.</p>
<div class="highlight"><pre><span></span>mix ecto.migrate
</pre></div>
<p>And to great success we now have <code>:has_2fa</code> attached to our users! This flag is going to tell us which users to send a one time password to and which ones to just let slide through with only one piece of authentic evidence. (Note: two factor authentication won&rsquo;t protect anything if your passwords for both the system and your email are just <code>password</code>)</p>

<h2>We&rsquo;re gonna need some new routes</h2>

<p>We need a place to go to render our form for 2fa, and when we&rsquo;re there, we need a way for our user to send their one time password to the controller for examination and verification.</p>
<div class="highlight"><pre><span></span><span class="c1">### lib/two_factor_auth_web/router.ex ###</span>

<span class="n">get</span><span class="p">(</span><span class="s2">&quot;/sessions/new/two_factor_auth&quot;</span><span class="p">,</span> <span class="nc">TwoFactorAuthController</span><span class="p">,</span> <span class="ss">:new</span><span class="p">)</span>
<span class="n">post</span><span class="p">(</span><span class="s2">&quot;/sessions/new/two_factor_auth&quot;</span><span class="p">,</span> <span class="nc">TwoFactorAuthController</span><span class="p">,</span> <span class="ss">:create</span><span class="p">)</span>
</pre></div>
<p>And the corresponding form:</p>
<div class="highlight"><pre><span></span><span class="c1">### lib/two_factor_auth_web/templates/two_factor_auth/two_factor_auth.html.eex ###</span>

<span class="o">&lt;</span><span class="err">%</span><span class="o">=</span> <span class="n">form_for</span> <span class="na">@conn</span><span class="p">,</span> <span class="n">two_factor_auth_path</span><span class="p">(</span><span class="na">@conn</span><span class="p">,</span> <span class="ss">:create</span><span class="p">),</span> <span class="k">fn</span> <span class="n">f</span> <span class="o">-&gt;</span> <span class="err">%</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="n">label</span><span class="o">&gt;</span>
    <span class="ss">Code</span><span class="p">:</span> <span class="o">&lt;</span><span class="err">%</span><span class="o">=</span> <span class="n">text_input</span> <span class="n">f</span><span class="p">,</span> <span class="ss">:one_time_pass</span><span class="p">,</span> <span class="ss">class</span><span class="p">:</span> <span class="s2">&quot;qa-one_time_pass&quot;</span> <span class="err">%</span><span class="o">&gt;</span>
  <span class="o">&lt;/</span><span class="n">label</span><span class="o">&gt;</span>

  <span class="o">&lt;</span><span class="err">%</span><span class="o">=</span> <span class="n">submit</span> <span class="s2">&quot;Submit&quot;</span><span class="p">,</span> <span class="ss">class</span><span class="p">:</span> <span class="s2">&quot;qa-submit&quot;</span> <span class="err">%</span><span class="o">&gt;</span>
<span class="o">&lt;</span><span class="err">%</span> <span class="k">end</span> <span class="err">%</span><span class="o">&gt;</span>
</pre></div>
<h2>And now the all-powerfull controllers</h2>

<p>Before we can get to the meat and potatoes of two-factor authentication, we need to take a gander at our session controller and, using that shiny, new boolean on our users, make sure we&rsquo;re sending people to their appropriate destinations.</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">TwoFactorAuthWeb.SessionController</span> <span class="k">do</span>
  <span class="kn">use</span> <span class="nc">TwoFactorAuthWeb</span><span class="p">,</span> <span class="ss">:controller</span>
  <span class="kn">import</span> <span class="nc">Plug.Conn</span>

  <span class="kn">alias</span> <span class="nc">TwoFactorAuth.Guardian</span>
  <span class="kn">alias</span> <span class="nc">TwoFactorAuth.Accounts</span>
  <span class="kn">alias</span> <span class="nc">TwoFactorAuthWeb.Mailer</span>

  <span class="kd">def</span> <span class="n">new</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="bp">_</span><span class="p">),</span> <span class="ss">do</span><span class="p">:</span> <span class="n">render</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="s2">&quot;new.html&quot;</span><span class="p">)</span>

  <span class="kd">def</span> <span class="n">create</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">session_params</span><span class="p">)</span> <span class="k">do</span>
    <span class="c1"># You could use a nested case here, but withs are cool, too</span>
    <span class="n">with</span> <span class="p">{</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">user</span><span class="p">}</span> <span class="o">&lt;-</span> <span class="nc">Accounts</span><span class="o">.</span><span class="n">verify_login</span><span class="p">(</span><span class="n">session_params</span><span class="p">)</span> <span class="k">do</span>
      <span class="k">case</span> <span class="n">user</span><span class="o">.</span><span class="n">has_2fa</span> <span class="k">do</span>
        <span class="no">true</span> <span class="o">-&gt;</span>
          <span class="c1"># remember that code at the beginning... this is where it went</span>
          <span class="p">{</span><span class="n">token</span><span class="p">,</span> <span class="n">one_time_pass</span><span class="p">}</span> <span class="o">=</span> <span class="nc">Accounts</span><span class="o">.</span><span class="n">generate_one_time_pass</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
          <span class="nc">Mailer</span><span class="o">.</span><span class="n">deliver_2fa_email</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">one_time_pass</span><span class="p">)</span>

          <span class="n">conn</span>
          <span class="o">|&gt;</span> <span class="n">put_session</span><span class="p">(</span><span class="s2">&quot;user_secret&quot;</span><span class="p">,</span> <span class="p">%{</span><span class="s2">&quot;token&quot;</span> <span class="o">=&gt;</span> <span class="n">token</span><span class="p">,</span> <span class="s2">&quot;user_id&quot;</span> <span class="o">=&gt;</span> <span class="n">user_id</span><span class="p">})</span>
          <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:info</span><span class="p">,</span> <span class="s2">&quot;A heckin&#39; 2fa code has been sent to you! Isn&#39;t that cool?&quot;</span><span class="p">)</span>
          <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">302</span><span class="p">)</span>
          <span class="o">|&gt;</span> <span class="n">redirect</span><span class="p">(</span><span class="ss">to</span><span class="p">:</span> <span class="n">two_factor_auth_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:new</span><span class="p">))</span>

        <span class="no">false</span> <span class="o">-&gt;</span>
          <span class="n">conn</span>
          <span class="o">|&gt;</span> <span class="nc">Guardian.Plug</span><span class="o">.</span><span class="n">sign_in</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
          <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:info</span><span class="p">,</span> <span class="s2">&quot;Login successful! But you should enable two-factor auth ngl&quot;</span><span class="p">)</span>
          <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">302</span><span class="p">)</span>
          <span class="o">|&gt;</span> <span class="n">redirect</span><span class="p">(</span><span class="ss">to</span><span class="p">:</span> <span class="n">page_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:index</span><span class="p">))</span>
      <span class="k">end</span>
    <span class="k">else</span>
      <span class="p">{</span><span class="ss">:error</span><span class="p">,</span> <span class="bp">_</span><span class="p">}</span> <span class="o">-&gt;</span>
        <span class="n">conn</span>
        <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:error</span><span class="p">,</span> <span class="s2">&quot;You entered an invalid password or email!&quot;</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">401</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="n">render</span><span class="p">(</span><span class="s2">&quot;new.html&quot;</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>Here we verify the the email and password passed in through <code>session_params</code> and return <code>{:ok, user}</code>. If the user has enabled two-factor auth on their account, we will generate them a one time password and email it to them. The user will fail the second factor of the authentication process if they don&rsquo;t have access to their email or this one time password.</p>
<div class="highlight"><pre><span></span><span class="kd">defmodule</span> <span class="nc">TwoFactorAuthWeb.TwoFactorAuthController</span> <span class="k">do</span>
  <span class="kn">use</span> <span class="nc">TwoFactorAuthWeb</span><span class="p">,</span> <span class="ss">:controller</span>
  <span class="kn">import</span> <span class="nc">Plug.Conn</span>

  <span class="kn">alias</span> <span class="nc">TwoFactorAuth.Guardian</span>
  <span class="kn">alias</span> <span class="nc">TwoFactorAuth.Accounts</span>

  <span class="kd">def</span> <span class="n">new</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="bp">_</span><span class="p">)</span> <span class="k">do</span>
    <span class="c1"># we want to see if our token is empty, and if it is we redirect them back to the new session page</span>
    <span class="c1"># the goal here is to make sure we have the same conn that went through the session controller</span>
    <span class="n">with</span> <span class="p">%{}</span> <span class="o">&lt;-</span> <span class="nc">Auth</span><span class="o">.</span><span class="n">fetch_secret_from_session</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span> <span class="k">do</span>
      <span class="n">conn</span>
      <span class="o">|&gt;</span> <span class="n">render</span><span class="p">(</span><span class="s2">&quot;two_factor_auth.html&quot;</span><span class="p">,</span> <span class="ss">action</span><span class="p">:</span> <span class="n">tw</span>        <span class="c1"># just in case?</span>
<span class="mi">191</span>
<span class="n">o_factor_auth_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:create</span><span class="p">))</span>
    <span class="k">else</span>
    <span class="bp">_</span> <span class="o">-&gt;</span>
      <span class="n">conn</span>
      <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:error</span><span class="p">,</span> <span class="s2">&quot;Page not found&quot;</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">404</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">redirect</span><span class="p">(</span><span class="ss">to</span><span class="p">:</span> <span class="n">session_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:new</span><span class="p">))</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="kd">def</span> <span class="n">create</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="p">%{</span><span class="s2">&quot;one_time_pass&quot;</span> <span class="o">=&gt;</span> <span class="n">one_time_pass</span><span class="p">})</span> <span class="k">do</span>
    <span class="c1"># to verify the one_time_pass that comes in through the form we need the secret token off the conn</span>
    <span class="c1"># we also need the user_id to know who we&#39;re building the session for</span>
    <span class="p">%{</span><span class="s2">&quot;token&quot;</span> <span class="o">=&gt;</span> <span class="n">token</span><span class="p">,</span> <span class="s2">&quot;user_id&quot;</span> <span class="o">=&gt;</span> <span class="n">user_id</span><span class="p">}</span> <span class="o">=</span> <span class="n">get_session</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
    <span class="n">user</span> <span class="o">=</span> <span class="nc">Accounts</span><span class="o">.</span><span class="n">get_user!</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>

    <span class="k">case</span> <span class="nc">Accounts</span><span class="o">.</span><span class="n">valid_one_time_pass?</span><span class="p">(</span><span class="n">one_time_pass</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span> <span class="k">do</span>
      <span class="no">true</span> <span class="o">-&gt;</span>
        <span class="n">conn</span>
        <span class="c1"># our one time password can only be used... once</span>
        <span class="c1"># but we wanna go that extra mile and also invalidate it... just in case</span>
        <span class="o">|&gt;</span> <span class="n">delete_session</span><span class="p">(</span><span class="s2">&quot;user_secret&quot;</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="nc">Guardian.Plug</span><span class="o">.</span><span class="n">sign_in</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:info</span><span class="p">,</span> <span class="s2">&quot;Login successful!&quot;</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">302</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="n">redirect</span><span class="p">(</span><span class="ss">to</span><span class="p">:</span> <span class="n">page_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:index</span><span class="p">))</span>

      <span class="no">false</span> <span class="o">-&gt;</span>
        <span class="n">conn</span>
        <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:error</span><span class="p">,</span> <span class="s2">&quot;The authentication code you entered was invalid!&quot;</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">401</span><span class="p">)</span>
        <span class="o">|&gt;</span> <span class="n">render</span><span class="p">(</span><span class="s2">&quot;two_factor_auth.html&quot;</span><span class="p">,</span> <span class="ss">action</span><span class="p">:</span> <span class="n">two_factor_auth_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:create</span><span class="p">))</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<h2>The legend of Plug.Conn</h2>

<p>There&rsquo;s a couple of challenges when it comes to dealing with the second factor of our authentication workflow. We need to be able to assure that there is one continuous session throughout the entire process, meaning that we can&rsquo;t take any requests from a user that hasn&rsquo;t first logged in with their username and password. We also need to be sure no sensitive data, i.e. our secret token, is being leaked to the user.</p>

<p>That&rsquo;s where <code>:plug_session</code> comes in. This is the session store in <code>conn[:private]</code> that get&rsquo;s encrypted when it&rsquo;s sent to the client and is stored by your browser as a cookie. We&rsquo;ll need to use <code>put_session/3</code> and <code>get_session/2</code> from <code>Plug.Conn</code> to assign and fetch our <code>&quot;user_secret&quot;</code> to and from the session.</p>
<div class="highlight"><pre><span></span><span class="c1">### from Plug.Conn (conn.ex) ###</span>

<span class="kd">def</span> <span class="n">put_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="ow">when</span> <span class="n">is_atom</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="n">is_binary</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">do</span>
<span class="n">put_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="o">&amp;</span><span class="nc">Map</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="ni">&amp;1</span><span class="p">,</span> <span class="n">session_key</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">value</span><span class="p">))</span>
<span class="k">end</span>

<span class="kd">defp</span> <span class="n">put_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">fun</span><span class="p">)</span> <span class="k">do</span>
<span class="n">private</span> <span class="o">=</span>
<span class="n">conn</span><span class="o">.</span><span class="n">private</span>
<span class="o">|&gt;</span> <span class="nc">Map</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="ss">:plug_session</span><span class="p">,</span> <span class="n">fun</span><span class="o">.</span><span class="p">(</span><span class="n">get_session</span><span class="p">(</span><span class="n">conn</span><span class="p">)))</span>
<span class="o">|&gt;</span> <span class="nc">Map</span><span class="o">.</span><span class="n">put_new</span><span class="p">(</span><span class="ss">:plug_session_info</span><span class="p">,</span> <span class="ss">:write</span><span class="p">)</span>

<span class="p">%{</span><span class="n">conn</span> <span class="o">|</span> <span class="ss">private</span><span class="p">:</span> <span class="n">private</span><span class="p">}</span>
<span class="k">end</span>
</pre></div>
<p><code>put_session</code> takes your connection, the new key, and the value you want to assign to that key and puts them in <code>:plug_session</code> which lives in the private store of you connection.</p>

<p><code>conn[:private]</code> is meant to be used by libraries and frameworks, such as <code>Plug.Conn</code>, to avoid writing to the user storage (the <code>:assigns</code> field).</p>

<p>So inside of our <code>conn</code> lives a special <code>:private</code> map that keeps our deep, dark secrets away from the user instead of leaking this information through <code>conn[:assigns]</code>. It&rsquo;s meant to be used by libraries, such as <code>Plug.Conn</code>, to avoid writing to <code>:assigns</code>. Take a gander:</p>
<div class="highlight"><pre><span></span><span class="p">%</span><span class="nc">Plug.Conn</span><span class="p">{</span>
  <span class="ss">private</span><span class="p">:</span> <span class="p">%{</span>
    <span class="ss">:phoenix_action</span> <span class="o">=&gt;</span> <span class="ss">:new</span><span class="p">,</span>
    <span class="ss">:phoenix_controller</span> <span class="o">=&gt;</span> <span class="nc">TwoFactorAuthWeb.TwoFactorAuthController</span><span class="p">,</span>
    <span class="ss">:phoenix_endpoint</span> <span class="o">=&gt;</span> <span class="nc">TwoFactorAuthWeb.Endpoint</span><span class="p">,</span>
    <span class="ss">:phoenix_flash</span> <span class="o">=&gt;</span> <span class="p">%{</span>
      <span class="s2">&quot;info&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;A two-factor authentication code has been sent to your email!&quot;</span>
    <span class="p">},</span>
    <span class="ss">:phoenix_format</span> <span class="o">=&gt;</span> <span class="s2">&quot;html&quot;</span><span class="p">,</span>
    <span class="ss">:phoenix_layout</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="nc">TwoFactorAuthWeb.LayoutView</span><span class="p">,</span> <span class="ss">:app</span><span class="p">},</span>
    <span class="ss">:phoenix_pipelines</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="ss">:browser</span><span class="p">],</span>
    <span class="ss">:phoenix_router</span> <span class="o">=&gt;</span> <span class="nc">TwoFactorAuthWeb.Router</span><span class="p">,</span>
    <span class="ss">:phoenix_view</span> <span class="o">=&gt;</span> <span class="nc">TwoFactorAuthWeb.TwoFactorAuthView</span><span class="p">,</span>
    <span class="ss">:plug_session</span> <span class="o">=&gt;</span> <span class="p">%{</span>
      <span class="s2">&quot;_csrf_token&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;MXbH2CPKOEs5iMltrA38ZQ==&quot;</span><span class="p">,</span>
      <span class="s2">&quot;guardian_default_token&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0d29fZmFjdG9yX2F1dGgiLCJleHAiOjE1NTExMzE1NDMsImlhdCI6MTU0ODcxMjM0MywiaXNzIjoidHdvX2ZhY3Rvcl9hdXRoIiwianRpIjoiYmMyMzUyZDktODk1Yi00N2ZiLTkzMWItNWNlY2I2OTcwMjMzIiwibmJmIjoxNTQ4NzEyMzQyLCJzdWIiOiIxIiwidHlwIjoiYWNjZXNzIn0.5rFnDhFhB28LxksKqt_sc0ZfgYv-QbuTX5PLFKJkgi7J4NzxKt5N-PphQT2Z39uMWbp3V2p22Fz1Yz3pqisfWw&quot;</span><span class="p">,</span>
      <span class="s2">&quot;phoenix_flash&quot;</span> <span class="o">=&gt;</span> <span class="p">%{</span>
        <span class="s2">&quot;info&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;A two-factor authentication code has been sent to your email!&quot;</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Here we&rsquo;re putting on the secret sauce during the first step of authentication and then sending the user along to the next stop:</p>
<div class="highlight"><pre><span></span><span class="c1">### lib/two_factor_auth_web/controllers/session_controller.ex ###</span>

<span class="n">conn</span>
<span class="o">|&gt;</span> <span class="n">put_session</span><span class="p">(</span><span class="s2">&quot;user_secret&quot;</span><span class="p">,</span> <span class="p">%{</span><span class="s2">&quot;token&quot;</span> <span class="o">=&gt;</span> <span class="n">token</span><span class="p">,</span> <span class="s2">&quot;user_id&quot;</span> <span class="o">=&gt;</span> <span class="n">user_id</span><span class="p">})</span>
<span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:info</span><span class="p">,</span> <span class="s2">&quot;A heckin&#39; 2fa code has been sent to you! Isn&#39;t that cool?&quot;</span><span class="p">)</span>
<span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">302</span><span class="p">)</span>
<span class="o">|&gt;</span> <span class="n">redirect</span><span class="p">(</span><span class="ss">to</span><span class="p">:</span> <span class="n">two_factor_auth_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="na">@new</span><span class="p">))</span>
</pre></div>
<p>Take a look at this! Our <code>&quot;user_secret&quot;</code> is now nested comfortable in <code>:plug_session</code>:</p>
<div class="highlight"><pre><span></span><span class="p">%</span><span class="nc">Plug.Conn</span><span class="p">{</span>
  <span class="ss">private</span><span class="p">:</span> <span class="p">%{</span>
    <span class="ss">:plug_session</span> <span class="o">=&gt;</span> <span class="p">%{</span>
      <span class="s2">&quot;_csrf_token&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;MXbH2CPKOEs5iMltrA38ZQ==&quot;</span><span class="p">,</span>
      <span class="s2">&quot;guardian_default_token&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0d29fZmFjdG9yX2F1dGgiLCJleHAiOjE1NTExMzE1NDMsImlhdCI6MTU0ODcxMjM0MywiaXNzIjoidHdvX2ZhY3Rvcl9hdXRoIiwianRpIjoiYmMyMzUyZDktODk1Yi00N2ZiLTkzMWItNWNlY2I2OTcwMjMzIiwibmJmIjoxNTQ4NzEyMzQyLCJzdWIiOiIxIiwidHlwIjoiYWNjZXNzIn0.5rFnDhFhB28LxksKqt_sc0ZfgYv-QbuTX5PLFKJkgi7J4NzxKt5N-PphQT2Z39uMWbp3V2p22Fz1Yz3pqisfWw&quot;</span><span class="p">,</span>
      <span class="s2">&quot;phoenix_flash&quot;</span> <span class="o">=&gt;</span> <span class="p">%{</span>
        <span class="s2">&quot;info&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;A two-factor authentication code has been sent to your email!&quot;</span>
      <span class="p">},</span>
      <span class="s2">&quot;user_secret&quot;</span> <span class="o">=&gt;</span> <span class="p">%{</span><span class="s2">&quot;token&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;some_token&quot;</span><span class="p">,</span> <span class="s2">&quot;user_id&quot;</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>When get&rsquo;s redirected to our new path, that&rsquo;s when we&rsquo;ll implement <code>get_session/2</code> to fetch our secret and check to see if we can even let them in and if we can, authenticate their one time password.</p>
<div class="highlight"><pre><span></span><span class="c1">### from Plug.Conn (conn.ex) ###</span>

<span class="kd">def</span> <span class="n">get_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> <span class="ow">when</span> <span class="n">is_atom</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="n">is_binary</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">do</span>
  <span class="n">conn</span> <span class="o">|&gt;</span> <span class="n">get_session</span> <span class="o">|&gt;</span> <span class="nc">Map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">session_key</span><span class="p">(</span><span class="n">key</span><span class="p">))</span>
<span class="k">end</span>

<span class="kd">defp</span> <span class="n">get_session</span><span class="p">(%</span><span class="nc">Conn</span><span class="p">{</span><span class="ss">private</span><span class="p">:</span> <span class="n">private</span><span class="p">})</span> <span class="k">do</span>
  <span class="k">if</span> <span class="n">session</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">private</span><span class="p">,</span> <span class="ss">:plug_session</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">session</span>
  <span class="k">else</span>
    <span class="k">raise</span> <span class="nc">ArgumentError</span><span class="p">,</span> <span class="s2">&quot;session not fetched, call fetch_session/2&quot;</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="kd">defp</span> <span class="n">session_key</span><span class="p">(</span><span class="n">binary</span><span class="p">)</span> <span class="ow">when</span> <span class="n">is_binary</span><span class="p">(</span><span class="n">binary</span><span class="p">),</span> <span class="ss">do</span><span class="p">:</span> <span class="n">binary</span>
<span class="kd">defp</span> <span class="n">session_key</span><span class="p">(</span><span class="n">atom</span><span class="p">)</span> <span class="ow">when</span> <span class="n">is_atom</span><span class="p">(</span><span class="n">atom</span><span class="p">),</span> <span class="ss">do</span><span class="p">:</span> <span class="nc">Atom</span><span class="o">.</span><span class="n">to_string</span><span class="p">(</span><span class="n">atom</span><span class="p">)</span>
</pre></div>
<p>After we retrieve our <code>&quot;user_secret&quot;</code>, we want to drop it from the session. Our one time password can only be used&hellip; well once. But, for an added measure of security we want to make sure that token doesn&rsquo;t exist anymore. This is where <code>delete_session/2</code> comes in, which works like a specialized version of <code>Map.delete/2</code>, but for the <code>:private</code> stuff on our <code>conn</code>.</p>
<div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">delete_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> <span class="ow">when</span> <span class="n">is_atom</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="n">is_binary</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">do</span>
  <span class="n">put_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="o">&amp;</span><span class="nc">Map</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="ni">&amp;1</span><span class="p">,</span> <span class="n">session_key</span><span class="p">(</span><span class="n">key</span><span class="p">)))</span>
<span class="k">end</span>

<span class="kd">defp</span> <span class="n">put_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">fun</span><span class="p">)</span> <span class="k">do</span>
<span class="n">private</span> <span class="o">=</span>
<span class="n">conn</span><span class="o">.</span><span class="n">private</span>
<span class="o">|&gt;</span> <span class="nc">Map</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="ss">:plug_session</span><span class="p">,</span> <span class="n">fun</span><span class="o">.</span><span class="p">(</span><span class="n">get_session</span><span class="p">(</span><span class="n">conn</span><span class="p">)))</span>
<span class="o">|&gt;</span> <span class="nc">Map</span><span class="o">.</span><span class="n">put_new</span><span class="p">(</span><span class="ss">:plug_session_info</span><span class="p">,</span> <span class="ss">:write</span><span class="p">)</span>

<span class="p">%{</span><span class="n">conn</span> <span class="o">|</span> <span class="ss">private</span><span class="p">:</span> <span class="n">private</span><span class="p">}</span>
<span class="k">end</span>
</pre></div>
<p>So now we have all the ingredients, assuming that the user has access to their email, for two successful pieces of evidence to finally sign them in to the system. That&rsquo;s where the create path from the <code>TwoFactorAuthController</code> comes in:</p>
<div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">create</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="p">%{</span><span class="s2">&quot;one_time_pass&quot;</span> <span class="o">=&gt;</span> <span class="n">one_time_pass</span><span class="p">})</span> <span class="k">do</span>
  <span class="c1"># to verify the one_time_pass we need the token off of the conn, which lives in the :private map</span>
  <span class="c1"># (specifically under :plug_session)</span>
  <span class="c1"># we also need the user_id to know who we&#39;re signing in</span>
  <span class="p">%{</span><span class="s2">&quot;token&quot;</span> <span class="o">=&gt;</span> <span class="n">token</span><span class="p">,</span> <span class="s2">&quot;user_id&quot;</span> <span class="o">=&gt;</span> <span class="n">user_id</span><span class="p">}</span> <span class="o">=</span> <span class="n">get_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="s2">&quot;user_secret&quot;</span><span class="p">)</span>
  <span class="n">user</span> <span class="o">=</span> <span class="nc">Accounts</span><span class="o">.</span><span class="n">get_user!</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>

  <span class="k">case</span> <span class="nc">Accounts</span><span class="o">.</span><span class="n">valid_one_time_pass?</span><span class="p">(</span><span class="n">one_time_pass</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span> <span class="k">do</span>
    <span class="no">true</span> <span class="o">-&gt;</span>
      <span class="n">conn</span>
      <span class="o">|&gt;</span> <span class="n">delete_session</span><span class="p">(</span><span class="s2">&quot;user_secret&quot;</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="nc">Guardian.Plug</span><span class="o">.</span><span class="n">sign_in</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:info</span><span class="p">,</span> <span class="s2">&quot;Login successful!&quot;</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">302</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">redirect</span><span class="p">(</span><span class="ss">to</span><span class="p">:</span> <span class="n">page_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:index</span><span class="p">))</span>

    <span class="no">false</span> <span class="o">-&gt;</span>
      <span class="n">conn</span>
      <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:error</span><span class="p">,</span> <span class="s2">&quot;The authentication code you entered was invalid!&quot;</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">401</span><span class="p">)</span>
      <span class="o">|&gt;</span> <span class="n">render</span><span class="p">(</span><span class="s2">&quot;two_factor_auth.html&quot;</span><span class="p">,</span> <span class="ss">action</span><span class="p">:</span> <span class="n">two_factor_auth_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:create</span><span class="p">))</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>
<h2>The cherry on top</h2>

<p>So what if our user doesn&rsquo;t recieve the email? Maybe some shark was nibbling on some transatlantic communications cable and something went wrong? Well, we could give our user the option to resend their email. We&rsquo;d just need a new route and some extra goodies in the controller to generate another one time password and token.</p>
<div class="highlight"><pre><span></span><span class="c1">### liv/two_factor_auth_web/router.ex ###</span>

<span class="n">post</span><span class="p">(</span><span class="s2">&quot;/sessions/new/two_factor_auth/resend_email&quot;</span><span class="p">,</span> <span class="nc">TwoFactorAuthController</span><span class="p">,</span> <span class="ss">:resend_email</span><span class="p">)</span>
</pre></div><div class="highlight"><pre><span></span><span class="c1">### lib/two_factor_auth_web/controllers/two_factor_auth_controller.ex ###</span>

<span class="kd">def</span> <span class="n">resend_email</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="bp">_</span><span class="p">)</span> <span class="k">do</span>
  <span class="p">%{</span><span class="s2">&quot;token&quot;</span> <span class="o">=&gt;</span> <span class="n">_old_token</span><span class="p">,</span> <span class="s2">&quot;user_id&quot;</span> <span class="o">=&gt;</span> <span class="n">user_id</span><span class="p">}</span> <span class="o">=</span> <span class="n">get_session</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="s2">&quot;user_secret&quot;</span><span class="p">)</span>
  <span class="n">user</span> <span class="o">=</span> <span class="nc">Accounts</span><span class="o">.</span><span class="n">get_user!</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>

  <span class="p">{</span><span class="n">new_token</span><span class="p">,</span> <span class="n">one_time_pass</span><span class="p">}</span> <span class="o">=</span> <span class="nc">Acconts</span><span class="o">.</span><span class="n">generate_one_time_pass</span><span class="p">()</span>
  <span class="nc">Mailer</span><span class="o">.</span><span class="n">deliver_2fa_email</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">one_time_pass</span><span class="p">)</span>

  <span class="n">conn</span>
  <span class="o">|&gt;</span> <span class="n">put_session</span><span class="p">(</span><span class="s2">&quot;user_secret&quot;</span><span class="p">,</span> <span class="p">%{</span><span class="s2">&quot;token&quot;</span> <span class="o">=&gt;</span> <span class="n">new_token</span><span class="p">,</span> <span class="s2">&quot;user_id&quot;</span> <span class="o">=&gt;</span> <span class="n">user_id</span><span class="p">})</span>
  <span class="o">|&gt;</span> <span class="n">put_flash</span><span class="p">(</span><span class="ss">:info</span><span class="p">,</span> <span class="s2">&quot;A new two-factor authentication code was sent to your email!&quot;</span><span class="p">)</span>
  <span class="o">|&gt;</span> <span class="n">put_status</span><span class="p">(</span><span class="mi">200</span><span class="p">)</span>
  <span class="o">|&gt;</span> <span class="n">render</span><span class="p">(</span><span class="s2">&quot;two_factor_auth.html&quot;</span><span class="p">,</span> <span class="ss">action</span><span class="p">:</span> <span class="n">two_factor_auth_path</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="ss">:create</span><span class="p">))</span>
<span class="k">end</span>
</pre></div>
<h2>So long</h2>

<p>As more and more services are moving away from email-based two-factor auth, is this solution useful? Sure it is! We (I) learned a lot by doing this. Mainly, I learned to read all the way through the docs when reading about a particular module *cough* <code>Plug.Conn</code> *cough*. Am I going to remember this lesson learned? Probably not. But that&rsquo;s besides the point. The information I&rsquo;ve presented to you, the wonderful reader, could come in handy with loads of other stuff.</p>

<p>Next time you&rsquo;re trying to pass weird and not-so-secure things from controller to controller, think back on this and ask yourself: is there a better way? Probably.</p>
]]>
      </description>
      <pubDate>Mon, 18 Mar 2019 10:01:41 -0400</pubDate>
      <link>https://teamgaslight.com/blog/two-factor-authentication-in-elixir-and-phoenix</link>
      <guid>https://teamgaslight.com/blog/two-factor-authentication-in-elixir-and-phoenix</guid>
    </item>
  </channel>
</rss>
