<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Isaac Bell]]></title><description><![CDATA[Isaac Bell is a software engineer in the U.S.]]></description><link>https://ibell.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 14 Sep 2026 20:58:34 GMT</lastBuildDate><atom:link href="https://ibell.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[3 Approaches to Mex Algorithms]]></title><description><![CDATA[Mex problems refer to the minimum non-negative integer that is not present in an array of positive integers. Solving Mex problems requires finding an efficient algorithm to determine the missing number. In this blog post, we’ll explore three differen...]]></description><link>https://ibell.hashnode.dev/mex-algorithms</link><guid isPermaLink="true">https://ibell.hashnode.dev/mex-algorithms</guid><category><![CDATA[algorithms]]></category><category><![CDATA[C++]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[Competitive programming]]></category><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Tue, 08 Aug 2023 21:00:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691528285162/2138d5d0-a85c-4997-9793-bac269eff8f4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Mex problems refer to the minimum non-negative integer that is not present in an array of positive integers. Solving Mex problems requires finding an efficient algorithm to determine the missing number. In this blog post, we’ll explore three different approaches to solving Mex problems.</p>
<h4 id="heading-1-quick-mex-for-small-array-values">1. Quick Mex for Small Array Values</h4>
<p>The first approach is to use a set when the values in the array are small, specifically when all values are less than 1 million. This approach takes advantage of the set’s constant time lookups. We can create a set and insert each element from the array into the set. Then we loop through the numbers from 0 to 1 million and return the first number that is not present in the set.</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">mex</span><span class="hljs-params">(<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&amp; numberArray)</span> </span>{
  <span class="hljs-built_in">set</span>&lt;<span class="hljs-keyword">int</span>&gt; sett;

  fo(i, numberArray.size()) 
    sett.insert(numberArray[i]);
  fo(i, <span class="hljs-number">1000001</span>)
    <span class="hljs-keyword">if</span>(!sett.count(i)) <span class="hljs-keyword">return</span> i;
  <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
}
</code></pre>
<p>Additionally, this approach can be optimized further with coordinate compression.</p>
<h4 id="heading-2-sorting-approach">2. Sorting Approach</h4>
<p>The second approach involves sorting the array and then looping through the sorted array. We start with <code>mex</code>as 1 and increment it whenever we come across a number that is equal to <code>mex</code>. After the loop, <code>mex</code> will be the answer. This approach takes <code>O(N log N)</code>time.</p>
<pre><code class="lang-cpp">sortall(numberArray);
<span class="hljs-keyword">int</span> mex = <span class="hljs-number">1</span>;
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> e : numberArray) {
 <span class="hljs-keyword">if</span> (e == mex) {
  mex++;
 }
}
</code></pre>
<h4 id="heading-3-more-sophisticated-approach">3. More Sophisticated Approach</h4>
<p>The third approach is a more sophisticated approach that involves removing elements greater than <code>N</code> from the array, sorting the array, and then analyzing the sequence. This approach takes <code>O(N log N)</code>time. The steps are as follows:</p>
<p>1. Go through the array and remove elements that are greater than <code>N</code>.</p>
<p>2. Sort the array.</p>
<p>3. Traverse the sequence and look at the first number that does not correspond to the position in the array.</p>
<p>For example, if we have an array [0, 3, 5, 7, 2, 4, 1, 10, 19] and N = 9, we would remove the numbers greater than 9, leaving us with [0, 3, 5, 7, 2, 4, 1].</p>
<p>Then, we would sort the array to get [0, 1, 2, 3, 4, 5, 7].</p>
<p>Finally, we would traverse the sorted array and look for the first number that does not correspond to its position. In this case, the first number that doesn’t match its position is 6, so the answer is 6.</p>
<h4 id="heading-conclusion">Conclusion</h4>
<p>There are multiple approaches to solving Mex problems, and each approach has its own advantages and limitations. When deciding which approach to use, consider the size of the array and the required time complexity.</p>
<p>If you have questions or comments, please leave them below. Stay tuned for a continuation on how to perform offline MEX queries.</p>
]]></content:encoded></item><item><title><![CDATA[Beginner’s Guide to Ruby Benchmarking]]></title><description><![CDATA[This is a quick step-by-step guide for when you need to do some performance testing on the fly.
Ruby has a built-in benchmarking module that is simple to use and effective enough to cover your standard use cases. Using one of a few functions, we can ...]]></description><link>https://ibell.hashnode.dev/beginners-guide-to-ruby-benchmarking-dc1f2e8a3d2b</link><guid isPermaLink="true">https://ibell.hashnode.dev/beginners-guide-to-ruby-benchmarking-dc1f2e8a3d2b</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Fri, 27 May 2022 20:58:24 GMT</pubDate><content:encoded><![CDATA[<p>This is a quick step-by-step guide for when you need to do some performance testing on the fly.</p>
<p>Ruby has a built-in <a target="_blank" href="https://ruby-doc.org/stdlib-2.7.1/libdoc/benchmark/rdoc/Benchmark.html">benchmarking module</a> that is simple to use and effective enough to cover your standard use cases. Using one of a few functions, we can quickly isolate non-performant sections of our code.</p>
<h3 id="heading-benchmark-reporting">Benchmark Reporting</h3>
<p>The <code>Benchmark.bm</code> method gives a printout of performance metrics for any blocks of code we pass into it. We can separate this into multiple chunks of code to execute, to test different things at once. We will receive multiple reports, one for each use of the <code>report</code> method.</p>
<p>Benchmark.bm do |bench|<br />  bench.report('Performance Test 1') do  </p>
<h1 id="heading-execute-some-code-here">execute some code here</h1>
<p>  end<br />  bench.report('Performance Test 2') do  </p>
<h1 id="heading-execute-some-other-code-here">execute some other code here</h1>
<p>  end<br />end</p>
<p>For this tutorial, we’ll only be testing one code block:</p>
<p>Benchmark.bm do |bench|<br />  bench.report('Testing some code') do  </p>
<h1 id="heading-execute-some-code-here-1">execute some code here</h1>
<p>  end<br />end</p>
<p>This will give us output similar to the following:</p>
<pre><code>user       system     total       real  
<span class="hljs-number">0.544000</span>   <span class="hljs-number">0.036000</span>   <span class="hljs-number">0.580000</span>    (<span class="hljs-number">1.049005</span>)
</code></pre><p>Each report displays the user CPU time, system CPU time, the combined sum CPU time, and the elapsed real time.</p>
<p>The unit of time is seconds.</p>
<p>So our code ran in about 1.05 seconds overall.</p>
<p>Let’s take this a step further and profile our code more thoroughly.</p>
<h3 id="heading-code-profiling">Code Profiling</h3>
<p>We want to get an accurate impression of how long our code will take to run on a small sample size of data. Then we’ll assess how well the code will perform with a larger pool of data.</p>
<p>Benchmark.bm do |bench|<br />  bench.report('Testing some code') do<br />    process_100_records<br />  end<br />end</p>
<p>Let’s run this benchmark 5 times and record the results.</p>
<pre><code> user       system     total       real  
Run <span class="hljs-number">1</span>: <span class="hljs-number">0.544000</span>   <span class="hljs-number">0.036000</span>   <span class="hljs-number">0.580000</span>    (<span class="hljs-number">1.049005</span>)  
Run <span class="hljs-number">2</span>: <span class="hljs-number">0.500000</span>   <span class="hljs-number">0.080000</span>   <span class="hljs-number">0.580000</span>    (<span class="hljs-number">1.059239</span>)  
Run <span class="hljs-number">3</span>: <span class="hljs-number">0.520000</span>   <span class="hljs-number">0.048000</span>   <span class="hljs-number">0.568000</span>    (<span class="hljs-number">1.026662</span>)  
Run <span class="hljs-number">4</span>: <span class="hljs-number">0.536000</span>   <span class="hljs-number">0.048000</span>   <span class="hljs-number">0.584000</span>    (<span class="hljs-number">1.066434</span>)  
Run <span class="hljs-number">5</span>: <span class="hljs-number">0.496000</span>   <span class="hljs-number">0.080000</span>   <span class="hljs-number">0.576000</span>    (<span class="hljs-number">1.050087</span>)
</code></pre><p>We’ll average the results. You may want the discard the minimum and maximum runtimes you receive, especially if they visibly deviate significantly from the mean.</p>
<p>For this tutorial, we’ll keep all 5 results.</p>
<p>Here is a quick script to determine what our expected runtime will be with the larger pool of data. For this example, we have a sample size of 100 records and a full data size of 1M records.</p>
<pre><code># This code can be run <span class="hljs-keyword">in</span> a terminal - just edit the variables
</code></pre><pre><code>def avg(array)  
  array.sum(<span class="hljs-number">0.0</span>) / array.size  
end  

def seconds_to_hms(sec)  
  <span class="hljs-string">"%02d:%02d:%02d"</span> % [sec / <span class="hljs-number">3600</span>, sec / <span class="hljs-number">60</span> % <span class="hljs-number">60</span>, sec % <span class="hljs-number">60</span>]  
end  

# Fill <span class="hljs-keyword">in</span> these variables <span class="hljs-keyword">with</span> your own results  
realtimes = [<span class="hljs-number">1.049005</span>, <span class="hljs-number">1.059239</span>, <span class="hljs-number">1.026662</span>, <span class="hljs-number">1.066434</span>, <span class="hljs-number">1.050087</span>]  
sample_size = <span class="hljs-number">100</span>  
full_data_size = <span class="hljs-number">1000000</span>
</code></pre><pre><code>average_time = avg(realtimes)
</code></pre><pre><code><span class="hljs-string">`# predicted runtime for full data size  
expected_runtime = average_time / sample_size * full_data_size  

p seconds_to_hms expected_runtime  

`</span>\=&gt; <span class="hljs-string">"02:55:02"</span>
</code></pre><p>This code will take about 3 hours to run(!)</p>
<p>Whether or not that is acceptable will depend on your use case, but now you have the info you need to make that determination.</p>
<p>I hope this helps. Good luck in the field!</p>
]]></content:encoded></item><item><title><![CDATA[Overriding I/O Streams in C++]]></title><description><![CDATA[POV: You have a struct/class which you want to add I/O capability to, but you don’t know how.
C++ lets us override the “>>” and “<<” operators, corresponding to input and output streams, respectively.
Let’s build an example; the Point structure holds...]]></description><link>https://ibell.hashnode.dev/you-have-a-struct-class-which-you-want-to-add-some-debugging-capability-to-abc2687edc6d</link><guid isPermaLink="true">https://ibell.hashnode.dev/you-have-a-struct-class-which-you-want-to-add-some-debugging-capability-to-abc2687edc6d</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Thu, 06 Jan 2022 17:03:29 GMT</pubDate><content:encoded><![CDATA[<p>POV: You have a struct/class which you want to add I/O capability to, but you don’t know how.</p>
<p>C++ lets us override the “&gt;&gt;” and “&lt;&lt;” operators, corresponding to input and output streams, respectively.</p>
<p>Let’s build an example; the Point structure holds two values, x and y. It prints information about itself using the <code>cout</code> function upon its creation.</p>
<p>struct Point {<br />  int x, y;</p>
<p>  Point(int _x, int _y): x(_x), y(_y) {<br />    std::cout &lt;&lt; "Created point with coordinates: " &lt;&lt; *this &lt;&lt; "\n";<br />  };<br />};</p>
<p>int main() {<br />  Point p(123, 456);</p>
<p>  return 0;<br />}</p>
<p>Running this code will break because our output stream does not know how to handle our custom data structure. We can override the <code>&lt;&lt;</code> operator to clearly define the behavior we want.</p>
<p>friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Point&amp; point) {<br />  return os &lt;&lt; point.x &lt;&lt; ' ' &lt;&lt; point.y;<br />}</p>
<p>Adding this class function will cause <code>cout</code> or any other output streaming operation to print the point’s x and y coordinates, with a space separator.</p>
<p>Note that we declare our override to be a “friend function”. The output stream will be where this function is invoked, rather than from within our class.</p>
<p>— — —</p>
<p>Now let’s say we want to read in the point’s coordinates from an input source, such as arguments read through the CLI. We could do this by directly scanning the individual x and y numbers, but we’d like a more elegant solution.</p>
<p>struct Point {<br />  ...<br />};</p>
<p>int main() {<br />  Point p;<br />  cin &gt;&gt; p;</p>
<p>  return 0;<br />}</p>
<p>This can be achieved by overriding the <code>&gt;&gt;</code> operator. The implementation is nearly the same as what we did to override the <code>&lt;&lt;</code> operator. Note once again that this is a friend function; in this case, the function will be called from the <code>istream</code> class.</p>
<p>friend istream&amp; operator&gt;&gt;(istream&amp; is, Point&amp; point) {<br />  return is &gt;&gt; point.x &gt;&gt; ' ' &gt;&gt; point.y;<br />}</p>
<p>Putting this all together, our final example looks like this:</p>
<p>struct Point {<br />  int x, y;</p>
<p>  friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Point&amp; point) {<br />    return os &lt;&lt; point.x &lt;&lt; ' ' &lt;&lt; point.y;<br />  }</p>
<p>  friend istream&amp; operator&gt;&gt;(istream&amp; is, Point&amp; point) {<br />    return is &gt;&gt; point.x &gt;&gt; ' ' &gt;&gt; point.y;<br />  }</p>
<p>  Point(int _x, int _y): x(_x), y(_y) {<br />    std::cout &lt;&lt; "Created point with coordinates: " &lt;&lt; *this &lt;&lt; "\n";<br />  };<br />};</p>
<p>int main() {<br />  Point p;<br />  std::cin &gt;&gt; p;<br />  std::cout &lt;&lt; "Point coordinates: " &lt;&lt; p;  </p>
<p>  return 0;<br />}</p>
<p>That’s it, you’re all done. Happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Doom Emacs Cheatsheet]]></title><description><![CDATA[I wanted to share the cheatsheet I wrote for Doom Emacs commands. I wrote this one because the others I found online were out of date. I use and maintain this reference daily.
This is something of a living document, so the document can and will chang...]]></description><link>https://ibell.hashnode.dev/doom-emacs-cheatsheet-76cd6e2a4b9a</link><guid isPermaLink="true">https://ibell.hashnode.dev/doom-emacs-cheatsheet-76cd6e2a4b9a</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Sat, 30 Oct 2021 20:28:28 GMT</pubDate><content:encoded><![CDATA[<p>I wanted to share the cheatsheet I wrote for Doom Emacs commands. I wrote this one because the others I found online were out of date. I use and maintain this reference daily.</p>
<p>This is something of a living document, so the document can and will change over time. This command list is not exhaustive, but it does cover all the commands I use regularly.</p>
<p>I also have a quick and dirty write-up for <strong>Magit</strong> window commands <a target="_blank" href="https://medium.com/@ibell/using-magit-1b65c7cad0b8">available here</a>. Be warned that it’s far less comprehensive than this list, but you may find it helpful for basic navigation inside the window.</p>
<p><strong>Last Updated:</strong> <em>January 2022</em></p>
]]></content:encoded></item><item><title><![CDATA[Using Magit]]></title><description><![CDATA[This article is intended as a quick and dirty reference for the “Magit” Git interface in Doom Emacs.
For those unfamiliar with Magit itself, here is an expository blog post and an intro guide.
Several of the commands in this article are only availabl...]]></description><link>https://ibell.hashnode.dev/using-magit-1b65c7cad0b8</link><guid isPermaLink="true">https://ibell.hashnode.dev/using-magit-1b65c7cad0b8</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Sat, 30 Oct 2021 20:22:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691604784729/819a9928-c592-4c6c-9821-1bd68fb77ff2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article is intended as a quick and dirty reference for the “Magit” Git interface in Doom Emacs.</p>
<p>For those unfamiliar with Magit itself, here is an expository <a target="_blank" href="https://emacsair.me/2017/09/01/the-magical-git-interface/">blog post</a> and an <a target="_blank" href="https://emacsair.me/2017/09/01/magit-walk-through/">intro guide</a>.</p>
<p>Several of the commands in this article are only available (by default) in Doom Emacs. To see a general reference guide for Magit, see the link below:</p>
<p><strong>General Reference Sheet:</strong></p>
<p>[<strong>Magit for Emacs</strong><br /><em>Edit description</em>kapeli.com](https://kapeli.com/cheat_sheets/Magit_for_Emacs.docset/Contents/Resources/Documents/index "https://kapeli.com/cheat_sheets/Magit_for_Emacs.docset/Contents/Resources/Documents/index")<a target="_blank" href="https://kapeli.com/cheat_sheets/Magit_for_Emacs.docset/Contents/Resources/Documents/index"></a></p>
<p>What follows below is a basic set of commands to remember while navigating Magit in Doom Emacs.</p>
<h3 id="heading-commands-at-a-glance">Commands At a Glance:</h3>
<p><strong>Initialize Git Repository:</strong></p>
<p><code>M-x magit-init</code></p>
<p><strong>Navigate to the Magit Window:</strong></p>
<p><code>SPC-g-g or C-x g</code></p>
<p><strong>In the Magit Window</strong></p>
<p>Select files or folders to stage, and stage them with the command <code>S</code>.</p>
<p>Unstage files with command <code>u</code>.</p>
<p>Once you’ve staged all files and folders you want, use command <code>C</code>to create a commit.</p>
<p>Press <code>TAB</code>to expand file diffs.</p>
<p>Enter a commit message, then close the commit buffer and save the commit using the Vim command <code>:wq</code>or <code>:x</code>.</p>
<p>To open a file, select the file and press <code>ENTER</code>.</p>
<p><strong>Merging and Squashing</strong></p>
<p>In the Magit Window, use the command <code>M</code>.</p>
<p>The following commands become available:</p>
<p>Close the merge actions buffer using <code>C-g</code></p>
<p><strong>Remotes</strong></p>
<p>To bring up the <strong>Remotes</strong> window, press <code>M</code> in the Magit Window.</p>
<p>The following commands become available:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691604782879/3a855b36-1abd-41ef-a536-509b553ee76c.png" alt /></p>
<p><strong>Pushing/Pulling</strong></p>
<p>Push with the command <code>p</code>.</p>
<p>Pull with the command <code>F</code>.</p>
<p>Fetch with the command <code>f</code>.</p>
]]></content:encoded></item><item><title><![CDATA[Rails: CORS Preflight Options Requests]]></title><description><![CDATA[CORS header ‘Access-Control-Allow-Origin’ missing
You’re probably here because you’ve run into an error similar to the following response from your API call:
The request was redirected to 'https://example.com/foo', which is disallowed for cross-origi...]]></description><link>https://ibell.hashnode.dev/rails-cors-preflight-options-requests-e93b2acb7282</link><guid isPermaLink="true">https://ibell.hashnode.dev/rails-cors-preflight-options-requests-e93b2acb7282</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Fri, 30 Aug 2019 04:00:44 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-cors-header-access-control-allow-origin-missing">CORS header ‘Access-Control-Allow-Origin’ missing</h3>
<p>You’re probably here because you’ve run into an error similar to the following response from your API call:</p>
<p>The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight</p>
<p>or</p>
<p>Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://your-domain.com/endpoint (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)</p>
<p>You will want to read the MDN docs on <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests">Preflight Requests</a> to get acquainted with the reasons behind this issue.</p>
<p>You can resolve this issue using something like the following code in <code>ApplicationController</code>:</p>
<p>before_action :cors_set_access_control_headers  </p>
<p>def cors_preflight_check<br />  if request.method == 'OPTIONS'<br />    cors_set_access_control_headers<br />    render text: '', content_type: 'text/plain'<br />  end<br />end  </p>
<p>protected  </p>
<p>def cors_set_access_control_headers<br />  response.headers['Access-Control-Allow-Origin'] = '*'<br />  response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, PATCH, DELETE, OPTIONS'<br />  response.headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token, Auth-Token, Email, X-User-Token, X-User-Email'<br />  response.headers['Access-Control-Max-Age'] = '1728000'<br />end</p>
<p>Then, add a catch-all to your <code>routes.rb</code> file which matches all OPTIONS requests.</p>
<p>match '*all', controller: 'application', action: 'cors_preflight_check', via: [:options]</p>
<p>Sources:</p>
<p><a target="_blank" href="https://gist.github.com/jpbalarini/54a1aa22ebb261af9d8bfd9a24e811f0">https://gist.github.com/jpbalarini/54a1aa22ebb261af9d8bfd9a24e811f0</a></p>
<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests">MDN CORS Primer: Preflight Requests</a></p>
]]></content:encoded></item><item><title><![CDATA[The Ruby Command Pattern — Pt. 2]]></title><description><![CDATA[Welcome back.
Let’s look at another example use of the Command Pattern in Ruby. This time, to give you a better idea of how it looks in practice (as opposed to the more conceptual explanation from the first article), we’ll make an extremely small-sca...]]></description><link>https://ibell.hashnode.dev/the-ruby-command-pattern-pt-2-ccec713d126c</link><guid isPermaLink="true">https://ibell.hashnode.dev/the-ruby-command-pattern-pt-2-ccec713d126c</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Sat, 13 Jul 2019 18:16:09 GMT</pubDate><content:encoded><![CDATA[<p>Welcome back.</p>
<p>Let’s look at another example use of the <a target="_blank" href="http://wiki.c2.com/?CommandPattern">Command Pattern</a> in Ruby. This time, to give you a better idea of how it looks <em>in practice</em> (as opposed to the more conceptual explanation from the first article), we’ll make an extremely small-scale example.</p>
<p>We’ll use the <a target="_blank" href="https://github.com/karmajunkie/imperator"><em>Imperator</em></a> gem to define a simple Command. Given a User model that handles an email, password, &amp;&amp; an ID, we will set up a Command to create a new user. This command could be could be called from our model, controller, using background tasks, within other commands, etc.</p>
<p>Here is <em>Imperator</em>’s description of Commands:</p>
<blockquote>
<p><em>Commands give you the opportunity to encapsulate all of the logic required for an interaction in one spot. Sometimes that interaction is as simple as a method call — more often there are several method calls involved, not all of which deal with domain logic (and thus, are inappropriate for inclusion on the models). Commands give you a place to bring all of these together in one spot without increasing coupling in your controllers or models.</em></p>
</blockquote>
<p>For our sample code, let’s assume the command code is placed in an <code>app/commands</code> directory. Let's also assume we have a separate <code>Notifier</code>class lying around which sends error logs.</p>
<pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">Command</span>::<span class="hljs-title">CreateUser</span>** &lt; <span class="hljs-title">Imperator</span>::<span class="hljs-title">Command</span>  
  **<span class="hljs-title">include</span>** <span class="hljs-title">ActiveModel</span>::<span class="hljs-title">Validations</span></span>
</code></pre><pre><code> integer :id  
  <span class="hljs-attr">string</span>  :email  
  <span class="hljs-attr">string</span>  :password
</code></pre><pre><code> validates_presence_of :id  
  <span class="hljs-attr">validates_presence_of</span> :email  
  <span class="hljs-attr">validates_presence_of</span> :password
</code></pre><pre><code> **def** **action**  
    **<span class="hljs-keyword">if</span>** !user.valid?  
      notify(  
        <span class="hljs-string">"Invalid attributes passed to Command::CreateUser"</span>,  
        user  
      )  
    **<span class="hljs-keyword">else</span>**  
      user.save  
    **end**  
  **end**  

  **def** **notify**(error_message, user)  
    # This is just an example  
    Notifier.notify(error_message, user)  
  **end**  

  **def** **user**  
    @user ||= User.new.tap **<span class="hljs-keyword">do</span>** |u|  
      u.id       = id  
      u.username = username  
      u.password = password  
    **end**  
  **end**  
**end**
</code></pre><p>Here’s how this code breaks down:</p>
<ol>
<li><code>action</code> is the main method which Imperator commands start from. We check if the attributes the command we received are valid, based on the validations set directly above.</li>
<li>If the attributes are not valid, we send out an error notification using our imaginary <code>Notifier</code> class.</li>
<li>If they are valid, we save the user. If you are doing something like synchronizing your data through an API, you might want to write a separate <code>SaveUser</code> command or similar to encapsulate that logic separately.</li>
<li>Depending on how complex your logic is going to be, you might take this and add a separate command for the <code>Notifier</code> or for error handling in general.</li>
</ol>
<p>All of this is done without having to rely on a model or create a service with lots of moving parts. This is obviously extremely useful once you are working on a larger code-base with lots of moving parts. The Command structure can help you de-couple your logic from specific models, controllers, services, etc., by setting up designated tasks which handle specific and specialized responsibilities.</p>
]]></content:encoded></item><item><title><![CDATA[The Ruby Command Pattern — Pt. 1]]></title><description><![CDATA[An Asynchronous Back-End Processing Methodology
Using Rails, what if we need to encapsulate some side/background processing which runs completely independently of our web server MVC functions? We can use tools like Sidekiq, Resque, and Cron, yes. But...]]></description><link>https://ibell.hashnode.dev/the-ruby-command-pattern-pt-1-ad6711af0722</link><guid isPermaLink="true">https://ibell.hashnode.dev/the-ruby-command-pattern-pt-1-ad6711af0722</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Sat, 13 Jul 2019 18:13:54 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-an-asynchronous-back-end-processing-methodology">An Asynchronous Back-End Processing Methodology</h3>
<p>Using Rails, what if we need to encapsulate some side/background processing which runs completely independently of our web server MVC functions? We can use tools like Sidekiq, Resque, and Cron, yes. But from an architecture standpoint, how do we <em>design</em> our back-end processing workflow?</p>
<p>For a real-world example, let’s say we have a large-scale shopping application. While our application is busy handling customer transactions, account changes, pre-orders, and the like, we may also need to do extensive background processing so that we can store accurate records of all transactions to a private data store via, say, AWS. Plus, while this happens we may need to run regularly scheduled updates (let’s say one every three hours) to ensure that our data stays in sync between both sources.</p>
<p>The Gang of Four (four co-authors, that is) <a target="_blank" href="https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8">Design Patterns</a> book illustrates lots of great examples of how to deal with various Object-Oriented pitfalls. Recommended reading for anybody interested.</p>
<h3 id="heading-the-command-pattern">The Command Pattern</h3>
<p>One lesser-known design pattern, the <a target="_blank" href="http://wiki.c2.com/?CommandPattern">Command</a> Pattern, serves as a useful bridge. The Command Pattern is pretty simple, in reality it’s a very similar idea to closures in functional programming. It serves a somewhat similar use, as well. With Commands in Ruby we can encapsulate a self-contained request, worker, data transfer or any other sort of process as an object. This allows us to offload these operations into corresponding classes which can run on their own, concurrently or asynchronously. This Command can be designed to be equivalent to a pure function, or at least be written to produce minimal (if any) side effects outside of its own scope. It will run its own validations on the input it is given, and determine interactions without placing added responsibility on your data models or controllers.</p>
<p>Ultimately, not that different from <a target="_blank" href="https://stackoverflow.com/a/111111/6848375">closures</a>.</p>
<h3 id="heading-in-practice-background-processing-commands">In Practice — Background Processing Commands</h3>
<p>Getting confused? Let’s make an example. Instead of starting of with a very basic example, I wanted to start with a real-world usage you might implement on a large-scale Rails application. If you want to start with the bare basics, go ahead and skip to <a target="_blank" href="https://plutos-reprieve.com/rails-command-pattern-pt-2/">part two</a>.</p>
<p>Let’s say we have a store where users order resume-writing services. We have a class that we use to make API calls which retrieve records. We’ll use the <a target="_blank" href="https://github.com/karmajunkie/imperator">Imperator</a> gem to set up our Command structure.</p>
<p>Add this to your Gemfile: <code>gem 'imperator'</code>. This will also include the <a target="_blank" href="https://github.com/solnic/virtus">Virtus</a>gem as a dependency, for declarative attribute handling.</p>
<pre><code># my_store_api.rb  
**<span class="hljs-built_in">require</span>** <span class="hljs-string">'rest-client'</span>  
**<span class="hljs-built_in">require</span>** <span class="hljs-string">'restclient'</span>
</code></pre><pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">MyStoreAPI</span>**  

    <span class="hljs-title">cattr_accessor</span> :<span class="hljs-title">whatever_auth</span></span>
</code></pre><pre><code> **<span class="hljs-class"><span class="hljs-keyword">class</span>** &lt;&lt; <span class="hljs-title">self</span>  
        **<span class="hljs-title">def</span>** **<span class="hljs-title">authorize</span>**  
            # <span class="hljs-title">do</span> <span class="hljs-title">some</span> <span class="hljs-title">stuff</span>  
            <span class="hljs-title">whatever_token</span> </span>= the_result  
        **end**
</code></pre><pre><code> # GET <span class="hljs-string">"https://fake-store.com/customers  
        **def** **get_customers**(options = {})  
            white_listed = %i(since name email city state)  
            get_with_parameters('/customers', whitelisted, options)  
        **end**</span>
</code></pre><pre><code> # GET <span class="hljs-string">"https://fake-store.com/orders  
        **def** **get_orders**(options = {})  
            white_listed = %i(since resume_id author_id customer_id)  
            get_with_parameters('/orders', whitelisted, options)  
        **end**</span>
</code></pre><pre><code> private
</code></pre><pre><code> **def** **get_with_parameters**(endpoint, whitelisted = [], options = {})  
          # Call our API endpoint  
        **end**  
    **end**  
**end**
</code></pre><p>Now, let’s say that every few hours, we need to do some processing and syncing on our back-end. We need to check which orders have successfully shipped, which are still pending approval, and which have been shipped but not received.</p>
<p>We can extract this into a Command which we will fire off in asynchronous queues. We can use any queue system such as Delayed Job, Resque, Sidekiq, etc. Here’s an example of what our Command can look like.</p>
<pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">SyncOrdersFromAPI</span>** &lt; <span class="hljs-title">Imperator</span>::<span class="hljs-title">Command</span>  
  <span class="hljs-title">datetime</span> <span class="hljs-title">since</span>, <span class="hljs-title">default</span>: <span class="hljs-title">Customer</span>.<span class="hljs-title">not_synced</span>.<span class="hljs-title">first</span>.<span class="hljs-title">created_at</span>  
  <span class="hljs-title">attribute</span> <span class="hljs-title">should_log_orders</span>, <span class="hljs-title">Virtus</span>::<span class="hljs-title">Attribute</span>::<span class="hljs-title">Boolean</span></span>
</code></pre><pre><code> # This method required, we run our main <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">here</span>  
  **<span class="hljs-title">def</span>** **<span class="hljs-title">action</span>**  
    <span class="hljs-title">orders</span>.<span class="hljs-title">in_groups_of</span>(<span class="hljs-params"><span class="hljs-number">1000</span></span>).**<span class="hljs-title">do</span>** |<span class="hljs-title">batch</span>|  
      <span class="hljs-title">process_orders</span>(<span class="hljs-params">batch</span>)  
    **<span class="hljs-title">end</span>**  
  **<span class="hljs-title">end</span>**</span>
</code></pre><pre><code> private
</code></pre><pre><code> **def** **orders**  
    @orders ||= MyStoreAPI.get_orders(since: since)  
  **end**
</code></pre><pre><code> **def** **sync_to_datastore**  
    process_order(order)  
    do_some_logging_on_order(order) **<span class="hljs-keyword">if</span>** should_log_orders  
  **end**
</code></pre><pre><code> **def** **do_some_logging_on_order**(order)  
    # Logger.info(order)  
    # EmailNotifier.notify_order_synced(order)  
    puts <span class="hljs-string">"synced order #{order.inspect}"</span>  
  **end**
</code></pre><pre><code> **def** **process_orders**(orders)  
    # <span class="hljs-keyword">do</span> some processing and save to cold storage  
    orders.find_each { |order| sync_to_datastore(order) }  
  **end**  
**end**
</code></pre><p>Pretty straightforward, but very useful if you need to do a lot of validation and complicated logic such as batch processing, logging, syncing, or large background queries. We could add validations and dynamically suspend operations depending on what is going on in our core domain at runtime, by passing in relevant flags or runtime state details as attributes. In this way, we are able to keep our core application logic and our background processor logic isolated from one another. This is pretty straightforward and maintainable.</p>
<p>In our Sidekiq initializer we can call our Command like so:</p>
<pre><code>Sidekiq.configure_server **<span class="hljs-keyword">do</span>** |config|  
  config.periodic **<span class="hljs-keyword">do</span>** |mgr|  
    # see **any** crontab **reference** **<span class="hljs-keyword">for</span>** the **first** argument  
    # e.g. **http**:<span class="hljs-comment">//www.adminschoice.com/crontab-**quick**-**reference**  </span>
    # **or**   https:<span class="hljs-comment">//crontab.guru/</span>
</code></pre><pre><code> mgr.register(  
      <span class="hljs-string">'0 */3 * * *'</span>, # Runs every <span class="hljs-number">3</span> hours  
      SyncOrdersFromAPI,   
      {   
        <span class="hljs-attr">retry</span>: <span class="hljs-number">2</span>,  
        <span class="hljs-attr">queue</span>: <span class="hljs-string">'foo'</span>  
      }  
    )  
  **end**  
**end**
</code></pre><p>Hopefully this gives you an idea of how to run Commands in Ruby/Rails, and how we can use this to set up isolated/encapsulated logic modules. This functionality can be expanded on to a very deep degree; let me know if you end up trying this out on your background processing system.</p>
<p>See you next time.</p>
]]></content:encoded></item><item><title><![CDATA[Removing QUnit from Your Ember Build]]></title><description><![CDATA[Tired of seeing Error: No tests were run in the console of your Ember application's dev environment?
Want to throw out QUnit from your Ember app? It’s not always so simple as deleting your /test folder, and it can be a bit of a pain in the side.
Well...]]></description><link>https://ibell.hashnode.dev/removing-qunit-from-your-ember-build-ea2f0c9b3b24</link><guid isPermaLink="true">https://ibell.hashnode.dev/removing-qunit-from-your-ember-build-ea2f0c9b3b24</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Sat, 01 Jun 2019 23:44:45 GMT</pubDate><content:encoded><![CDATA[<p>Tired of seeing <code>Error: No tests were run</code> in the console of your Ember application's dev environment?</p>
<p>Want to throw out QUnit from your Ember app? It’s not always so simple as deleting your /test folder, and it can be a bit of a pain in the side.</p>
<p>Well if you don’t, I don’t know why you’re here, but read on, I guess. We can do this in a simple series of steps. It’s pretty intuitive to remove QUnit using Grunt, so far as I can tell, and so for this tutorial we’ll assume you are struggling with this task using Bower and/or NPM includes.</p>
<h3 id="heading-set-test-flag-to-false-in-ember-cli-build">Set “Test” Flag to False in Ember CLI Build</h3>
<p>Modify your <code>ember-cli-build.js</code> like so:</p>
<pre><code><span class="hljs-built_in">module</span>.exports = **<span class="hljs-function"><span class="hljs-keyword">function</span>**(<span class="hljs-params">defaults</span>) </span>{  
   **<span class="hljs-keyword">var</span>** app = **<span class="hljs-keyword">new</span>** EmberApp(defaults, {  
+    tests: <span class="hljs-literal">false</span>,  
     <span class="hljs-string">'ember-cli-babel'</span>: {  
       <span class="hljs-attr">presets</span>: [<span class="hljs-string">"env"</span>],  
       <span class="hljs-attr">plugins</span>: [<span class="hljs-string">"transform-es2015-arrow-functions"</span>],
</code></pre><p>Note line 3.</p>
<h3 id="heading-remove-imports-from-the-ember-cli-build">Remove Imports from the Ember CLI Build</h3>
<p>Remove any QUnit and Ember-QUnit imports from your <code>ember-cli-build.js</code>i.e.:</p>
<pre><code>- app.**<span class="hljs-keyword">import</span>**(<span class="hljs-string">'bower_components/qunit/qunit/qunit.js'</span>);  
- app.**<span class="hljs-keyword">import</span>**(<span class="hljs-string">'bower_components/ember-qunit/ember-qunit.amd.js'</span>);
</code></pre><p>Remove any of the following packages from your <code>package.json</code> and/or <code>bower.json</code>.</p>
<ul>
<li>“qunit”</li>
<li>“ember-qunit”</li>
<li>“ember-cli-test-loader” [Optional]</li>
<li>“phantomjs” [Optional]</li>
<li>“ember-qunit-notifications”</li>
<li>“ember-cli-qunit”</li>
</ul>
<h3 id="heading-remove-any-test-scripts-from-your-ci">Remove Any Test Scripts from your CI</h3>
<p>Although this seems a bit counter-intuitive if you have one. <em>(Are you sure you want to remove your test suite from your CI?)</em></p>
<pre><code>script:  
   - npm run lint:hbs  
   - npm run lint:js  
   - npm test &lt;-- **<span class="hljs-keyword">delete</span>**
</code></pre><h3 id="heading-cli-cleanup-command">CLI Cleanup Command</h3>
<p>Let’s clean our caches and get rid of un-used dependency folders. In other words, let’s refresh our modules folders.</p>
<pre><code>$ bower **cache** clean &amp;&amp; bower **install** --force &amp;&amp; bower prune &amp;&amp; rm -rf node_modules &amp;&amp; npm cache clean --force &amp;&amp; npm i
</code></pre>]]></content:encoded></item><item><title><![CDATA[Let’s Debug: MetaSploit -“socket: Operation not permitted”]]></title><description><![CDATA[This is a breakdown of an error you might encounter with Metasploit depending on your Linux setup and user permissions.
Our Error
msf5 auxiliary(scanner/ip/ipidseq) > show options
Module options (auxiliary/scanner/ip/ipidseq):
 Name       Current Set...]]></description><link>https://ibell.hashnode.dev/lets-debug-metasploit-socket-operation-not-permitted-8e94d8a8b117</link><guid isPermaLink="true">https://ibell.hashnode.dev/lets-debug-metasploit-socket-operation-not-permitted-8e94d8a8b117</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Sat, 01 Jun 2019 23:41:28 GMT</pubDate><content:encoded><![CDATA[<p>This is a breakdown of an error you might encounter with Metasploit depending on your Linux setup and user permissions.</p>
<h3 id="heading-our-error">Our Error</h3>
<pre><code>msf5 auxiliary(scanner/ip/ipidseq) &gt; show options
</code></pre><pre><code>Module options (auxiliary/scanner/ip/ipidseq):
</code></pre><pre><code> Name       Current Setting  Required  Description  
   ----       ---------------  --------  -----------  
   INTERFACE                   no        The name **<span class="hljs-keyword">of</span>** the interface  
   RHOSTS     <span class="hljs-number">192.168</span><span class="hljs-number">.1</span><span class="hljs-number">.0</span>/<span class="hljs-number">24</span>   yes       The target address range **or** CIDR identifier  
   RPORT      <span class="hljs-number">80</span>               yes       The target port  
   SNAPLEN    <span class="hljs-number">65535</span>            yes       The number **<span class="hljs-keyword">of</span>** bytes to capture  
   THREADS    <span class="hljs-number">50</span>               yes       The number **<span class="hljs-keyword">of</span>** concurrent threads  
   TIMEOUT    <span class="hljs-number">500</span>              yes       The reply read timeout **<span class="hljs-keyword">in</span>** milliseconds
</code></pre><pre><code>msf5 auxiliary(scanner/ip/ipidseq) &gt; run  
<span class="hljs-attr">SIOCSIFFLAGS</span>: Operation **not** permitted  
<span class="hljs-attr">SIOCSIFFLAGS</span>: Operation **not** permitted  
<span class="hljs-attr">SIOCSIFFLAGS</span>: Operation **not** permitted  
...
</code></pre><pre><code>[-] Auxiliary failed: RuntimeError wlp3s0: You don<span class="hljs-string">'t have permission to capture on that device (socket: Operation not permitted)  
[-] Call stack:  
[-]   /opt/metasploit-framework/lib/msf/core/exploit/capture.rb:124:in `open_live'</span>  
[-]   /opt/metasploit-framework/lib/msf/core/exploit/capture.rb:<span class="hljs-number">124</span>:**<span class="hljs-keyword">in</span>** <span class="hljs-string">`open_pcap'  
[-]   /opt/metasploit-framework/modules/auxiliary/scanner/ip/ipidseq.rb:51:in `</span>run_host<span class="hljs-string">'  
[-]   /opt/metasploit-framework/lib/msf/core/auxiliary/scanner.rb:111:in `block (2 levels) in run'</span>  
[-]   /opt/metasploit-framework/lib/msf/core/thread_manager.rb:<span class="hljs-number">106</span>:**<span class="hljs-keyword">in</span>** <span class="hljs-string">`block in spawn'  
[*] Auxiliary module execution completed</span>
</code></pre><h3 id="heading-our-investigation">Our Investigation</h3>
<p>If you aren’t already doing so, you may want to test on your local IP 127.0.1.0 — you should still see the same error if all is as expected.</p>
<p>Relevant Github Issue: <a target="_blank" href="https://github.com/rapid7/metasploit-framework/issues/10721">https://github.com/rapid7/metasploit-framework/issues/10721</a></p>
<p>Relevant AskUbuntu Issue: <a target="_blank" href="https://askubuntu.com/questions/530920/tcpdump-permissions-problem">https://askubuntu.com/questions/530920/tcpdump-permissions-problem</a></p>
<p>This issue stems from either lack of permissions granted to the <code>tcpdump</code>tool, or issues with <code>pcap</code> installation in possible combination with missing <code>setcap</code> permissions.</p>
<h3 id="heading-questions-to-consider">Questions to Consider</h3>
<p>Do you have <code>tcpdump</code> installed? In Linux try:</p>
<pre><code>**ls** -la /usr/sbin | grep tcpdump
</code></pre><p>and see if you get some output similar to this.</p>
<pre><code>-rwxr-x--- <span class="hljs-number">1</span> root pcap <span class="hljs-number">1130096</span> Mar <span class="hljs-number">31</span>  <span class="hljs-number">2018</span> /usr/sbin/tcpdump
</code></pre><p>Make sure you’ve given tcpdump the <a target="_blank" href="https://askubuntu.com/a/632189">proper permissions it needs</a>.</p>
<p>Also, you probably need to start running MSF as a root user if you aren’t already.</p>
<h3 id="heading-resolution">Resolution</h3>
<p>Try these commands on Linux:</p>
<pre><code>sudo setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby)  
sudo setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap)  
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
</code></pre><p>and run MSF from scratch.</p>
<p>Again, are you a root user? If not, you will either need to run MSF as a root user (probably changing much of your configuration in the process) or you will need to change your user ID and group ID to 0 in your etcpassword file.</p>
<p>Keep in mind, it is extremely easy to lock yourself out of your computer messing around with this in particular, so make sure you really know what you’re doing and don’t edit this file while you’re logged in as the same user you’re editing. You could lose your sudo privileges at a very inopportune time, and find yourself stuck.</p>
<p><em>Further Information:</em></p>
<p><a target="_blank" href="https://www.cyberciti.biz/faq/understanding-etcpasswd-file-format/">https://www.cyberciti.biz/faq/understanding-etcpasswd-file-format/</a></p>
<p><a target="_blank" href="https://www.poftut.com/change-user-password-passwd-linux-etc-passwd-file/">https://www.poftut.com/change-user-password-passwd-linux-etc-passwd-file/</a></p>
]]></content:encoded></item><item><title><![CDATA[Let’s Debug: Curb Gem Installation Failed]]></title><description><![CDATA[The Problem
You see this when you try to bundle your gems in a new Rails app.
**ERROR**:  Error installing curb:  
**ERROR**: Failed to build gem native extension.
/usr/local/rvm/rubies/ruby-2.1.2/bin/ruby extconf.rb  
checking **for** curl-config......]]></description><link>https://ibell.hashnode.dev/lets-debug-curb-gem-installation-failed-15af6237dc52</link><guid isPermaLink="true">https://ibell.hashnode.dev/lets-debug-curb-gem-installation-failed-15af6237dc52</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Sat, 01 Jun 2019 23:37:18 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-the-problem">The Problem</h3>
<p>You see this when you try to bundle your gems in a new Rails app.</p>
<pre><code>**ERROR**:  <span class="hljs-built_in">Error</span> installing curb:  
**ERROR**: Failed to build gem native extension.
</code></pre><pre><code>/usr/local/rvm/rubies/ruby<span class="hljs-number">-2.1</span><span class="hljs-number">.2</span>/bin/ruby extconf.rb  
checking **<span class="hljs-keyword">for</span>** curl-config... no  
checking **<span class="hljs-keyword">for</span>** main() **<span class="hljs-keyword">in</span>** -lcurl... no
</code></pre><pre><code>*** extconf.rb failed ***
</code></pre><pre><code>Could **not** create Makefile due to some reason, probably lack **<span class="hljs-keyword">of</span>** necessary  
libraries **and**<span class="hljs-comment">/**or** headers.  Check the mkmf.log file **for** more details.  You may  
need configuration options.</span>
</code></pre><h3 id="heading-the-cause">The Cause</h3>
<p>Windows users, I don’t have a solution for you. My apologies.</p>
<p>Curb depends on some native machine bindings which you’ll need to download as libraries. Specifically, it needs the <code>libcurl3</code> and/or <code>libcurl4</code>libraries installed on your machine if you are on a Linux machine.</p>
<p>On OSX, the issue is a bit more complicated. See below.</p>
<h3 id="heading-the-solution">The Solution</h3>
<h3 id="heading-mac-updated-as-of-101319">Mac (Updated as of 10/13/19)</h3>
<p>Curb can no longer be installed via Homebrew, because it is no longer maintained by its author. This was previously the best way to install the gem on OS X.</p>
<p>[<strong>Delete curb.rb by core-code · Pull Request #54794 · Homebrew/homebrew-cask</strong><br /><em>You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or…</em>github.com](https://github.com/Homebrew/homebrew-cask/pull/54794 "https://github.com/Homebrew/homebrew-cask/pull/54794")<a target="_blank" href="https://github.com/Homebrew/homebrew-cask/pull/54794"></a></p>
<p>The <a target="_blank" href="https://github.com/taf2/curb">Github repository</a> still exists, and it is possible to force wrestle it into your version of OS X, but understand that there is no official support from any vendors. Most likely, you will have to search through Github Issues for the gem to find a work-around for your Mac environment and OS Version.</p>
<p>Here are some leads to get you started:</p>
<ul>
<li><a target="_blank" href="https://github.com/taf2/curb/issues/391">Curb 0.9.6 on macOS Catalina</a></li>
<li><a target="_blank" href="https://github.com/taf2/curb/issues/389">Curb 0.8.8 on OS X 10.14 Mojave</a></li>
</ul>
<h3 id="heading-linux">Linux</h3>
<p>First, run sudo apt-get update.</p>
<p>On Ubuntu:</p>
<pre><code>sudo apt-**get** install libcurl4-gnutls-dev libcurl3 libcurl4-openssl-dev
</code></pre><p>On RedHat:</p>
<pre><code>$ sudo yum install ruby-devel libcurl-devel openssl-devel
</code></pre><p>You may need to install the <code>curl-devel</code> package as well depending on your platform.</p>
<pre><code>yum **install** curl-devel
</code></pre><p>Then try installation again.</p>
<p>If this helps you, or if you’d like to send over any corrections, feel free to reach out. Good luck from here on!</p>
]]></content:encoded></item><item><title><![CDATA[Troubleshooting Elastic Beanstalk Memory Issues]]></title><description><![CDATA[First question: Is it your logs?
Check your events, you may see something like this here
AWS EBS/EC2: No Disk Space Left on Device
If you came to this article with an emergency situation on your application here’s the quick and dirty: There are diffe...]]></description><link>https://ibell.hashnode.dev/troubleshooting-elastic-beanstalk-memory-issues-cd60069bf8b8</link><guid isPermaLink="true">https://ibell.hashnode.dev/troubleshooting-elastic-beanstalk-memory-issues-cd60069bf8b8</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Mon, 25 Feb 2019 19:35:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691604802621/32c64ffc-acd7-4fed-864f-f10e437eb87a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-first-question-is-it-your-logs">First question: Is it your logs?</h4>
<p>Check your events, you may see something like this here</p>
<h3 id="heading-aws-ebsec2-no-disk-space-left-on-device"><strong>AWS EBS/EC2: No Disk Space Left on Device</strong></h3>
<p>If you came to this article with an emergency situation on your application here’s the quick and dirty: There are different reasons why your EC2 instance might run out of memory, but it is very common to run into this error because AWS logs are clogging up your instance.</p>
<p>You’re probably here because your Elastic Beanstalk environment’s Health Level went from OK to Severe. Frantically, you tried to download Full Logs to see where things went wrong, but the EBS console gave you the following error: <code>Error: Rate Exceeded</code> .</p>
<p>You only panicked for a few moments before you realized you could run <code>eb logs</code> from your terminal and poke around there. Or maybe you used <code>eb ssh</code> to log into your EC2 instance, and took a look at your logs only to realize that the logs themselves are the issue.</p>
<p>Here’s some quick steps towards a resolution.</p>
<h3 id="heading-check-your-memory-usage">Check Your Memory Usage</h3>
<p>SSH into the EC2 instance and print out a breakdown of the memory usage.</p>
<p>Disk Space Check:</p>
<p>df [-h | -a]</p>
<p>Memory Usage Check:</p>
<p>du -ahx / | sort -rh | head -20</p>
<p>Check file sizes in a directory:</p>
<p>du -sh /var/app/current/log/*</p>
<p>If your results look something like this:</p>
<p>$ df -h</p>
<p>Filesystem Size Used Avail Use% Mounted on</p>
<p>devtmpfs 3.9G 60K 3.9G 1% /dev</p>
<p>tmpfs 3.9G 0 3.9G 0% /dev/shm</p>
<p>/dev/xvda1 7.8G 5.4G 2.4G 100% /</p>
<p>$ du -ahx / | sort -rh | head -20</p>
<p>7.6G /</p>
<p>2.3G /var</p>
<p>2.2G /opt</p>
<p>2.0G /var/app/current/log</p>
<p>2.0G /var/app/current</p>
<p>2.0G /var/app</p>
<p>2.0G /opt/rubies</p>
<p>1.5G /var/app/current/sidekiq.log</p>
<p>1.4G /var/app/current/log/production.log</p>
<p>1.2G /var/app/containerfiles/logs/rotated</p>
<p>(everything below under 1G)</p>
<p>$ du -sh /var/app/containerfiles/logs/rotated/*</p>
<p>7.0M production.log1551081661.gz</p>
<p>6.0M production.log1551085261.gz</p>
<p>39M production.log1551088861.gz</p>
<p>66M production.log1551092461.gz</p>
<p>66M production.log1551096061.gz</p>
<p>1.2G production.log1551099661</p>
<p>0 production.log1551103262</p>
<p>0 production.log1551106862</p>
<p>0 production.log1551110461</p>
<p>notice that the log files are way to big (in this case, the larger log files would be millions of lines long).</p>
<p>You’ll want to check the files to make sure that no critical info is in them. If it is, consider making a copy of the file to your local machine or copying relevant text from the file.</p>
<p>When you’re ready, remove all text from the files which are too large (DON’T delete them or you may encounter other issues).</p>
<blockquote>
<p>sudo truncate -s 0 /var/app/current/log/production.log</p>
<p>sudo truncate -s 0 /var/app/current/log/sidekiq.log</p>
<p>sudo truncate -s 0 /var/app/containerfiles/logs/rotated/production.log1551099661</p>
</blockquote>
<p>If space is completely full, you can’t download Full Logs from EBS, but you can remove one or two less-useful log files and then download Full Logs from the EBS Console before you remove the rest.</p>
<p>Once you’ve removed the files which need blasting, your EBS environment will likely begin working as it should. But, the Health will probably still show Severe. Redeploy your environment and you should be good to go.</p>
<p>Consider looking into <a target="_blank" href="https://aws-labs.com/understanding-logrotate-utility/">Log Rotation Options</a> for your environment, possibly by uploading to <a target="_blank" href="http://www.dowdandassociates.com/blog/content/howto-rotate-logs-to-s3/">S3</a> using a service such as <a target="_blank" href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html">CloudWatch</a>.</p>
]]></content:encoded></item><item><title><![CDATA[HTML Canvas Tutorial — Create and Manipulate 2D Particles]]></title><description><![CDATA[We’ve come a long way since the basics of the browser. Tools such as Three.js and WebGL Studio, animation libraries such as Raphael.js or GSAP, the growing popularity of SVGs, and the past decade’s increasingly conducive changes to Javascript have tr...]]></description><link>https://ibell.hashnode.dev/html-canvas-tutorial-create-and-manipulate-2d-particles-f3a8513e744</link><guid isPermaLink="true">https://ibell.hashnode.dev/html-canvas-tutorial-create-and-manipulate-2d-particles-f3a8513e744</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Fri, 11 Jan 2019 08:19:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691604809399/74257cd5-a390-4f94-a35d-43e0ab57dec1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We’ve come a long way since the basics of the browser. Tools such as <a target="_blank" href="https://threejs.org/">Three.js</a> and <a target="_blank" href="https://webglstudio.org/">WebGL Studio</a>, animation libraries such as <a target="_blank" href="http://raphaeljs.com/">Raphael.js</a> or <a target="_blank" href="https://greensock.com/gsap">GSAP</a>, the growing popularity of <a target="_blank" href="https://w3techs.com/technologies/details/im-svg/all/all">SVGs</a>, and the past decade’s increasingly conducive changes to <a target="_blank" href="https://javascript.info/animation">Javascript</a> have transformed animations in the browser from an occasional novelty to something real and fun to play with. The HTML canvas is a great way to get your feet wet creating directly interactive visuals in the browser. But there’s a lot to animation, and it can be best to start small. In this tutorial, we will learn how to make a simple particle cloud using a full-screen canvas, animate it, and make it respond to user input.</p>
<p>By the end of this tutorial, you will have created an element consisting of<br />small color particles which rotate around the mouse position; when the left mouse button is held down, the particle effect will scale out to circle the entire screen. Hopefully this article will give any Canvas newcomer some ideas to play around with.</p>
<p>Try the demo here: <a target="_blank" href="http://particle-vortex.herokuapp.com/">http://particle-vortex.herokuapp.com/</a></p>
<p>Read the full source code here: <a target="_blank" href="https://github.com/IsaacBell/Canvas-Particle-Vortex">https://github.com/IsaacBell/Canvas-Particle-Vortex</a></p>
<h3 id="heading-initial-variables">Initial Variables</h3>
<p>Let’s set up the initial conditions and variables for the effect first. This way, we can make global changes in one place. This is where we’ll set our necessary variables for the canvas element.</p>
<pre><code># Initial Setup
</code></pre><pre><code>fps = <span class="hljs-number">30</span>   
width = <span class="hljs-built_in">window</span>.innerWidth  
height = <span class="hljs-built_in">window</span>.innerHeight  
r = <span class="hljs-number">70</span>  
scale = <span class="hljs-number">1</span>  
scaleMin = <span class="hljs-number">12.5</span>  
scaleMax = <span class="hljs-number">100</span>   
particleCount = <span class="hljs-number">250</span>  
canvas = <span class="hljs-literal">undefined</span>    # You can <span class="hljs-keyword">of</span> course omit <span class="hljs-built_in">this</span> line  
context = <span class="hljs-literal">undefined</span>   # Ditto  
particles = <span class="hljs-literal">undefined</span> # Ditto  
mouseX = width * <span class="hljs-number">0.5</span>  
mouseY = height * <span class="hljs-number">0.5</span>  
isMouseDown = <span class="hljs-literal">false</span>
</code></pre><p>We set a variable to store the size of the display window, we will pass this information to the canvas element in order to define its bounds. Variable <code>r</code> will determine the radius of the particle cloud. scale changes the size of the cloud, <code>scaleMin</code> allows us to set the absolute minimum scale of the cloud, and <code>scaleMax</code> allows you to set the maximum scale the cloud will reach when the user is holding the mouse down. <code>particleCount</code> allows you to increase or decrease the number of particles which appear the element; too many and we will run into performance issues. For the purpose of this demo, 30 FPS will work fine.</p>
<h3 id="heading-our-init-function">Our Init Function</h3>
<pre><code>**init** = -&gt;  
  # Create canvas element  
  canvas = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'canvas'</span>)  
  canvas.id  = <span class="hljs-string">'myCanvas'</span>  
  <span class="hljs-built_in">document</span>.body.appendChild(canvas)  
  **<span class="hljs-keyword">if</span>** canvas **and** canvas.getContext  
    context = canvas.getContext(<span class="hljs-string">'2d'</span>)  
    # Event handlers  
    <span class="hljs-built_in">window</span>.addEventListener <span class="hljs-string">'mousemove'</span>, onMouseMove, <span class="hljs-literal">false</span>  
    <span class="hljs-built_in">window</span>.addEventListener <span class="hljs-string">'mousedown'</span>, onMouseDown, <span class="hljs-literal">false</span>  
    <span class="hljs-built_in">window</span>.addEventListener <span class="hljs-string">'mouseup'</span>, onMouseUp, <span class="hljs-literal">false</span>  
    <span class="hljs-built_in">window</span>.addEventListener <span class="hljs-string">'onResize'</span>, onResize, <span class="hljs-literal">false</span>  
    createParticles()  
    onResize()  
    <span class="hljs-built_in">setInterval</span> animLoop, <span class="hljs-number">1000</span> / fps  
  **<span class="hljs-keyword">return</span>**
</code></pre><p>Here’s what happening in the code here:</p>
<p><strong>Step 1</strong></p>
<p>We create a canvas element, and set it’s corresponding HTML element id to “<em>myCanvas</em>”. You will need an element with this ID in your HTML to match.</p>
<p><strong>Step 2</strong></p>
<p>We append (add) the canvas element it to the body of our HTML. If we miss this step, the canvas will never appear since it isn’t being drawn/rendered in the HTML document anywhere</p>
<p><strong>Step 3</strong></p>
<p>If the canvas has been properly set and we’re able to do setup using getContext()</p>
<p>-&gt; We set our drawing context to ‘2D’</p>
<p>-&gt; We add event listeners for mouse events and browser resizing</p>
<p>-&gt; We call createParticles(), which we will use to generate our particle cloud</p>
<p>-&gt; We call onResize(), which will fit our canvas element to its needed proportions</p>
<p>-&gt; We set animLoop() to repeat at the rate of our fps variable</p>
<h3 id="heading-color">Color</h3>
<p>The first function we’ll define is colorLuminance(). We need this for when we generate our particles; we’ll use this when we brighten or darken the hex colors we’ll generate as we create our particle cloud. colorLuminance() takes two arguments, the first being the hex string representing a color and second being a decimal between 1 and -1, indicating how much to brighten or darken the hex color.</p>
<p>For more details on what’s going on here, check out this <a target="_blank" href="http://www.sitepoint.com/javascript-generate-lighter-darker-color/">article by Craig Buckler</a>.</p>
<pre><code>colorLuminance = (**hex**, lum) -&gt;  
  # validate hex string  
  **hex** = <span class="hljs-built_in">String</span>(**hex**).replace(<span class="hljs-regexp">/[^0-9a-f]/gi</span>, <span class="hljs-string">''</span>)   
  **<span class="hljs-keyword">if</span>** hex.length &lt; <span class="hljs-number">6</span>  
    **hex** = **hex**[<span class="hljs-number">0</span>] + **hex**[<span class="hljs-number">0</span>] + **hex**[<span class="hljs-number">1</span>] + **hex**[<span class="hljs-number">1</span>] + **hex**[<span class="hljs-number">2</span>] + **hex**[<span class="hljs-number">2</span>]  
  lum = lum **or** <span class="hljs-number">0</span>
</code></pre><pre><code> # convert to decimal and change luminosity  
  rgb = <span class="hljs-string">'#'</span>  
  c = <span class="hljs-literal">undefined</span>  
  i = <span class="hljs-literal">undefined</span>  
  i = <span class="hljs-number">0</span>  
  **<span class="hljs-keyword">while</span>** i &lt; <span class="hljs-number">3</span>  
    c = <span class="hljs-built_in">parseInt</span>(hex.substr(i * <span class="hljs-number">2</span>, <span class="hljs-number">2</span>), <span class="hljs-number">16</span>)  
    c = <span class="hljs-built_in">Math</span>.round(<span class="hljs-built_in">Math</span>.min(<span class="hljs-built_in">Math</span>.max(<span class="hljs-number">0</span>, c + c * lum), <span class="hljs-number">255</span>)).toString(<span class="hljs-number">16</span>)  
    rgb += (<span class="hljs-string">'00'</span> + c).substr(c.length)  
    i++  
  **<span class="hljs-keyword">return</span>** rgb
</code></pre><p>With that out of the way, let’s make the function that will serve as much of the meat of our project.</p>
<h3 id="heading-creating-our-particles">Creating Our Particles</h3>
<p>We’ll use a while loop to create an array of particles with randomized movement speeds, fill color, and orbit distance from the center of the cloud. The <code>fillColor</code> value makes use of the <code>colorLuminance()</code> function we just added previously; play around with this line to find a color range you like. The speed and orbit distance of each particle is randomized to an extent, by multiplying values times the value returned by <code>Math.random()</code>. This is a very common pattern in graphics/color processing.</p>
<pre><code>createParticles = -&gt;  
  particles = []  
  i = <span class="hljs-number">0</span>  
  **<span class="hljs-keyword">while</span>** i &lt; particleCount  
    particle =   
      size: <span class="hljs-number">5</span>  
      <span class="hljs-attr">position</span>:  
        x: mouseX  
        <span class="hljs-attr">y</span>: mouseY  
      <span class="hljs-attr">offset</span>:  
        x: <span class="hljs-number">0</span>  
        <span class="hljs-attr">y</span>: <span class="hljs-number">0</span>  
      <span class="hljs-attr">shift</span>:  
        x: mouseX  
        <span class="hljs-attr">y</span>: mouseY  
      <span class="hljs-attr">speed</span>: <span class="hljs-number">0.02</span> + <span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">0.02</span>  
      <span class="hljs-attr">targetSize</span>: <span class="hljs-number">1</span>  
      <span class="hljs-attr">fillColor</span>: colorLuminance(<span class="hljs-string">'#'</span> + <span class="hljs-built_in">Math</span>.random().toString(<span class="hljs-number">16</span>), <span class="hljs-number">-0.23</span>)  
      <span class="hljs-attr">orbit</span>: r / <span class="hljs-number">3</span> * <span class="hljs-built_in">Math</span>.random()  
    particles.push particle  
    i++  
  **<span class="hljs-keyword">return</span>**
</code></pre><h3 id="heading-responding-to-event-listeners">Responding to Event Listeners</h3>
<p>Next we’ll write the functions which will be triggered by the event listeners we set up earlier. Nothing too complicated, we simply store the mouse’s dynamic position and mouseDown status in our top-level variables. Lastly, when the browser window is resized, we will change the dimensions of the canvas element.</p>
<pre><code># Simple event Listener functions
</code></pre><pre><code>**onMouseMove** = (e) -&gt;  
  mouseX = e.clientX - ((<span class="hljs-built_in">window</span>.innerWidth - width) * <span class="hljs-number">.5</span>)  
  mouseY = e.clientY - ((<span class="hljs-built_in">window</span>.innerHeight - height) * <span class="hljs-number">.5</span>)  
  **<span class="hljs-keyword">return</span>**
</code></pre><pre><code>**onMouseDown** = -&gt;  
  isMouseDown = <span class="hljs-literal">true</span>
</code></pre><pre><code>**onMouseUp** = -&gt;  
  isMouseDown = <span class="hljs-literal">false</span>
</code></pre><pre><code>**onResize** = -&gt;  
  width = <span class="hljs-built_in">window</span>.innerWidth  
  height = <span class="hljs-built_in">window</span>.innerHeight  
  canvas.width = width  
  canvas.height = height  
  **<span class="hljs-keyword">return</span>**
</code></pre><h3 id="heading-the-animation-loop">The Animation Loop</h3>
<p>Now for the render loop itself. This is where the real action is; don’t get intimidated looking at it.</p>
<p>Here’s a breakdown of what we’re doing:</p>
<ul>
<li>We scale the particle cloud to its maximum or minimum size depending on whether the mouse is down</li>
<li>With context.fillStyle() we set a color to draw shapes in. We choose black, with 55% opacity</li>
<li>With context.fillRect() we draw up the bounds for the canvas rectangle we’ll be filling in</li>
<li>Using a simple while loop, we iterate through the particles and rotate, shift, and gently enlarge each as needed. The faster the fps variable is, the faster these shifts and rotations will appear to the eye</li>
<li>Once we’ve calculated the new size and position of our particle in each iteration, we use the canvas api to draw our circle</li>
</ul>
<pre><code>**animLoop** = -&gt;  
  **<span class="hljs-keyword">if</span>** isMouseDown  
    # Expand the cloud when mouse is clicked down  
    scale += (scaleMax - scale) * <span class="hljs-number">0.2</span>  
  **<span class="hljs-keyword">else</span>**  
    # Or <span class="hljs-keyword">else</span> shrink the cloud down  
    scale -= (scale - scaleMin) * <span class="hljs-number">0.2</span>  
  # Apply whichever change we set above  
  scale = <span class="hljs-built_in">Math</span>.min(scale, scaleMax)
</code></pre><pre><code> # <span class="hljs-built_in">Set</span> our line opacity and limit our drawing board   
  # size to the size <span class="hljs-keyword">of</span> the screen  
  context.fillStyle = <span class="hljs-string">'rgba(0,0,0,0.55)'</span>  
  context.fillRect <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, context.canvas.width, context.canvas.height  

  i = <span class="hljs-number">0</span>  
  len = particles.length  

  **<span class="hljs-keyword">while</span>** i &lt; len  
    particle = particles[i]  

    # Rotation  
    particle.offset.x += particle.speed * <span class="hljs-number">0.7</span>  
    particle.offset.y += particle.speed * <span class="hljs-number">0.7</span>  

    # Follow the mouse, <span class="hljs-keyword">with</span> a bit <span class="hljs-keyword">of</span> blur/lag effect  
    particle.shift.x += (mouseX - (particle.shift.x)) * particle.speed * <span class="hljs-number">0.6</span>  
    particle.shift.y += (mouseY - (particle.shift.y)) * particle.speed * <span class="hljs-number">0.6</span>  

    # Shift the particles accordingly, using a cosine <span class="hljs-function"><span class="hljs-keyword">function</span>  
    <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">x</span> = <span class="hljs-title">particle</span>.<span class="hljs-title">shift</span>.<span class="hljs-title">x</span> + <span class="hljs-title">Math</span>.<span class="hljs-title">cos</span>(<span class="hljs-params">i + particle.offset.x</span>) * <span class="hljs-title">particle</span>.<span class="hljs-title">orbit</span> * <span class="hljs-title">scale</span>  
    <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">y</span> = <span class="hljs-title">particle</span>.<span class="hljs-title">shift</span>.<span class="hljs-title">y</span> + <span class="hljs-title">Math</span>.<span class="hljs-title">sin</span>(<span class="hljs-params">i + particle.offset.y</span>) * <span class="hljs-title">particle</span>.<span class="hljs-title">orbit</span> * <span class="hljs-title">scale</span>  

    # <span class="hljs-title">Limit</span> <span class="hljs-title">our</span> <span class="hljs-title">animation</span> <span class="hljs-title">to</span> <span class="hljs-title">the</span> <span class="hljs-title">screen</span> <span class="hljs-title">bounds</span>  
    <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">x</span> = <span class="hljs-title">Math</span>.<span class="hljs-title">max</span>(<span class="hljs-params">Math.min(particle.position.x, width), <span class="hljs-number">0</span></span>)  
    <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">y</span> = <span class="hljs-title">Math</span>.<span class="hljs-title">max</span>(<span class="hljs-params">Math.min(particle.position.y, height), <span class="hljs-number">0</span></span>)  
    <span class="hljs-title">particle</span>.<span class="hljs-title">size</span> += (<span class="hljs-params">particle.targetSize - (particle.size)</span>) * 0.05  

    **<span class="hljs-title">if</span>** <span class="hljs-title">Math</span>.<span class="hljs-title">round</span>(<span class="hljs-params">particle.size</span>) == <span class="hljs-title">Math</span>.<span class="hljs-title">round</span>(<span class="hljs-params">particle.targetSize</span>)  
      <span class="hljs-title">particle</span>.<span class="hljs-title">targetSize</span> = 1 + <span class="hljs-title">Math</span>.<span class="hljs-title">random</span>(<span class="hljs-params"></span>) * 10  

    # <span class="hljs-title">Finally</span>, <span class="hljs-title">let</span>'<span class="hljs-title">s</span> <span class="hljs-title">do</span> <span class="hljs-title">some</span> <span class="hljs-title">drawing</span>!  

    <span class="hljs-title">context</span>.<span class="hljs-title">beginPath</span>(<span class="hljs-params"></span>)  

    # <span class="hljs-title">Select</span> <span class="hljs-title">line</span> <span class="hljs-title">color</span> <span class="hljs-title">at</span> <span class="hljs-title">random</span>  
    <span class="hljs-title">context</span>.<span class="hljs-title">fillStyle</span> = <span class="hljs-title">particle</span>.<span class="hljs-title">fillColor</span>  
    <span class="hljs-title">context</span>.<span class="hljs-title">strokeStyle</span> = <span class="hljs-title">particle</span>.<span class="hljs-title">fillColor</span>  
    <span class="hljs-title">context</span>.<span class="hljs-title">lineWidth</span> = <span class="hljs-title">particle</span>.<span class="hljs-title">size</span>  
    <span class="hljs-title">context</span>.<span class="hljs-title">moveTo</span> <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">x</span>, <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">y</span>  
    <span class="hljs-title">context</span>.<span class="hljs-title">lineTo</span> <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">x</span>, <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">y</span>  
    <span class="hljs-title">context</span>.<span class="hljs-title">stroke</span>(<span class="hljs-params"></span>)  
    <span class="hljs-title">context</span>.<span class="hljs-title">arc</span> <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">x</span>, <span class="hljs-title">particle</span>.<span class="hljs-title">position</span>.<span class="hljs-title">y</span>, <span class="hljs-title">particle</span>.<span class="hljs-title">size</span> / 2, 0, <span class="hljs-title">Math</span>.<span class="hljs-title">PI</span> * 2, <span class="hljs-title">true</span>  
    <span class="hljs-title">context</span>.<span class="hljs-title">fill</span>(<span class="hljs-params"></span>)  
    <span class="hljs-title">i</span>++  

  **<span class="hljs-title">return</span>**</span>
</code></pre><p>Lastly, we need to call our initializer function to jump things off.</p>
<pre><code><span class="hljs-built_in">window</span>.onload = init
</code></pre><h3 id="heading-conclusion">Conclusion</h3>
<p>Hopefully you can get an idea of how to bring fully interactive visuals to a web browser using the canvas. This demo could easily be expanded, optimized, or modified. There’s lots of potential. Play around with the variables, download the source on Github, experiment in your browser.</p>
<p>Github Repo: <a target="_blank" href="https://github.com/IsaacBell/Canvas-Particle-Vortex">https://github.com/IsaacBell/Canvas-Particle-Vortex</a></p>
]]></content:encoded></item><item><title><![CDATA[Introducing Twilio]]></title><description><![CDATA[Introducing Twilio
Twilio is a powerful cloud communications platform which provides an interface for SMS, voice call utilities, answering machines, virtual phone lines, and more. With this platform we can build a virtual communications system which ...]]></description><link>https://ibell.hashnode.dev/introducing-twilio-2ee82a5b357c</link><guid isPermaLink="true">https://ibell.hashnode.dev/introducing-twilio-2ee82a5b357c</guid><dc:creator><![CDATA[Isaac Bell]]></dc:creator><pubDate>Fri, 11 Jan 2019 07:46:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691604813537/8b4f53cd-c9dc-4fb0-b271-e7513defd3d0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introducing-twilio">Introducing Twilio</h3>
<p>Twilio is a powerful cloud communications platform which provides an interface for SMS, voice call utilities, answering machines, virtual phone lines, and more. With this platform we can build a virtual communications system which we can then count on to remain reliable in our applications as we deploy them to over 150 countries worldwide.</p>
<p>We’ll build a simple and easily extensible Ruby integration for the Twilio core platform, then use that to perform a few tasks:</p>
<ul>
<li>Sending <a target="_blank" href="https://www.twilio.com/docs/sms/send-messages">SMS</a> with Ruby</li>
<li>Verifying phone numbers via the <a target="_blank" href="https://www.twilio.com/docs/lookup/api">Lookup</a> API.</li>
<li>Then we’ll look at how to set up two-factor authentication using this service.</li>
</ul>
<p>We will not cover making calls with the service today, but that may be something I cover in the future if requested.</p>
<p>For the purpose of this tutorial we will be using Ruby on Rails.</p>
<h3 id="heading-you-will-need">You Will Need:</h3>
<ul>
<li>A Twilio account</li>
<li>Twilio test credentials including: Your Twilio <a target="_blank" href="https://support.twilio.com/hc/en-us/articles/223136607-What-is-an-Application-SID-">Account SID</a> Your <a target="_blank" href="https://support.twilio.com/hc/en-us/articles/223136027-Auth-Tokens-and-How-to-Change-Them">Authentication Token</a></li>
<li>At least one active Twilio phone number with Messaging enabled</li>
<li>[For Step 2] The Twilio Lookup API enabled</li>
</ul>
<h3 id="heading-general-tips">General Tips</h3>
<ol>
<li>Twilio has some hard rules as to their phone system. All numbers follow the <a target="_blank" href="https://www.twilio.com/docs/glossary/what-e164">E.164</a> international format code. To ensure our phone numbers follow this standard, we will use the <a target="_blank" href="https://github.com/joost/phony_rails">Phony</a> gem.</li>
<li>For international messaging, restrictions apply for some countries. A phone line from a particular country may be limited to sending only in that country or select others. To deal with this, I recommend buying multiple phone lines in order to cover all of the countries you need to. Twilio phone numbers (as I write this article in Q3 2018) are only $1, so it’s simple and cost-effective to get two or three to split sending between.</li>
</ol>
<p>If you are new to the platform, you should <a target="_blank" href="https://support.twilio.com/hc/en-us/articles/223183068-Twilio-international-phone-number-availability-and-their-capabilities">check whether phone lines are available in the area you want with the capabilities you need</a>. You should also read up on <a target="_blank" href="https://support.twilio.com/hc/en-us/sections/205553288-International-Messaging">Twilio’s International Messaging support page</a> to see if there are any gotchas for your country.</p>
<h3 id="heading-getting-started">Getting Started</h3>
<p>First, let’s add the <a target="_blank" href="https://github.com/twilio/twilio-ruby">Twilio Ruby gem</a> to our Ruby app. From your terminal, run:</p>
<pre><code>$ bundler add twilio-ruby
</code></pre><p>Or append <code>gem 'twilio-ruby'</code> to your Gemfile.</p>
<h3 id="heading-building-our-twilio-integration">Building Our Twilio Integration</h3>
<p><strong>Base Twilio Service</strong></p>
<p>Now, let’s start on our Twilio interface. First we will set up our base class which connects to the Twilio API.</p>
<p>Here we will implement the common <a target="_blank" href="https://www.toptal.com/ruby-on-rails/rails-service-objects-tutorial">Service</a> pattern to abstract the Twilio API connection. For this tutorial, we will create two sub-classes which pull from this base. We can then easily re-use this code from within any model or controller class.</p>
<pre><code>**<span class="hljs-built_in">require</span>** <span class="hljs-string">'twilio-ruby'</span>
</code></pre><pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">Services</span>::<span class="hljs-title">Twilio</span>**  
  <span class="hljs-title">cattr_accessor</span> :<span class="hljs-title">client_adapter</span>  
  **<span class="hljs-title">self</span>**.<span class="hljs-title">client_adapter</span> </span>= Twilio::REST::Client
</code></pre><pre><code> **attr_accessor** :client, :t_phone  

  **attr_reader** :user # Optional
</code></pre><pre><code> **def** **initialize**(opts = {})  
    # Here you might stop initialization or raise an error <span class="hljs-keyword">if</span>   
    # certain options are missing <span class="hljs-keyword">from</span> the argument hash  
    # i.e. <span class="hljs-string">`raise SomeError unless opts[:to].present?`</span>
</code></pre><pre><code> # Optional  
    @user = opts[:user]  

    # Twilio Credentials  
    @account_sid = <span class="hljs-string">'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'</span>  
    @auth_token  = <span class="hljs-string">'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'</span>  
    @client  = **self**.**<span class="hljs-class"><span class="hljs-keyword">class</span>**.<span class="hljs-title">client_adapter</span>.<span class="hljs-title">new</span>(@<span class="hljs-title">account_sid</span>, @<span class="hljs-title">auth_token</span>)  

    # <span class="hljs-title">Our</span> <span class="hljs-title">message</span>/<span class="hljs-title">payload</span> <span class="hljs-title">and</span> <span class="hljs-title">its</span> <span class="hljs-title">recipient</span>  
    @<span class="hljs-title">body</span> </span>= opts[:body]  
    @t_phone = opts[:to]  
  **end**  

  protected
</code></pre><pre><code> # Base message sending method  
  **def** **send**(options = {})  
    # Either leave <span class="hljs-built_in">this</span> section blank, or set up a <span class="hljs-keyword">default</span> send action  
    # <span class="hljs-keyword">for</span> your child service classes to inherit  

    # Here is an example <span class="hljs-keyword">of</span> a <span class="hljs-keyword">default</span> action -  
    # This base method will attempt to decide   
    # whether to make a call or text based on  
    # input args, then attempt to send the payload  
    options.reverse_merge!({  
      <span class="hljs-attr">to</span>: @t_phone,  
      <span class="hljs-attr">body</span>: @body,  
      <span class="hljs-attr">from</span>: @<span class="hljs-keyword">from</span>  
    }) **unless** @t_phone.blank?  

    **<span class="hljs-keyword">if</span>** options[:url].present? || options[:record]  
      # These options will only be present <span class="hljs-keyword">for</span> a call  
      @client.api.account.calls.create(options)  
    **<span class="hljs-keyword">else</span>**  
      @client.api.account.messages.create(options)  
    **end**  
  **end**  
**end**
</code></pre><p>First, we set up the <code>client_adapter</code> class attribute. This will be important because when we want to test our service, we can easily change this adapter to a mock version. Or, for your setup, you might like to call some other service if you are in a custom environment, say <em>staging</em>. More details on this later.</p>
<p>In the <code>initialize()</code> function we create a new instance of the Twilio client using our Twilio SID and authentication token.</p>
<p>The <code>send()</code> function here is just a parent method for child classes to pull from. Omit it at will without error. We are probably never going to call <code>Services::Twilio.send()</code> naked, but by adding this method to the parent class we can set up a default action for any of our child classes.</p>
<p>As it is written here, the parent <code>send()</code> method defaults to sending an SMS, and this will be the behavior of any Twilio service which inherits from this base class and doesn’t have its own <code>send()</code> method defined. You can tailor the default action to your needs, or omit it to get an error when <code>send()</code> is not defined in our child classes.</p>
<p><strong>Twilio SMS Service</strong></p>
<p>We will build a child class for each Twilio product we want to harness. First, let’s take a look at SMS delivery. For this, we will create a sub-class of our Twilio Base Service. This class is straightforward at its core; we will first override the <code>send()</code> method from our base class.</p>
<p>Below is a basic setup you can start from; using this setup, we take our <a target="_blank" href="https://stackoverflow.com/questions/18407618/what-are-options-hashes">options hash</a>, fill in any blank parameters with whatever relevant data the service object was initialized with, and pass the parameters to the Twilio API.</p>
<pre><code>**<span class="hljs-built_in">require</span>** <span class="hljs-string">'twilio-ruby'</span>
</code></pre><pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">Services</span>::<span class="hljs-title">Twilio</span>::<span class="hljs-title">SMS</span>** &lt; <span class="hljs-title">Services</span>::<span class="hljs-title">Twilio</span>  
  **<span class="hljs-title">def</span>** **<span class="hljs-title">send</span>**(<span class="hljs-title">options</span> </span>= {})  
    options.reverse_merge!({  
      :<span class="hljs-function"><span class="hljs-params">from</span> =&gt;</span> @<span class="hljs-keyword">from</span>,  
      :<span class="hljs-function"><span class="hljs-params">to</span>   =&gt;</span> @to || @t_phone,  
      :<span class="hljs-function"><span class="hljs-params">body</span> =&gt;</span> @body  
    })  
    @client.api.account.messages.create(options)  
  **end**  
**end**
</code></pre><p><strong>Extending Our SMS Service</strong></p>
<p>Below is an example of some ways you can extend this SMS service to handle your application’s needs. You may need to adjust some of this code based a few factors.</p>
<p>First, you may need to write a method to properly check and format the phone number we’ll be sending to. Using our <code>receiving_number</code> method, we can pull our target phone number from any data source we need to. Here, for example purposes, I have added a check for a <em>user</em> model with a <em>sms_number</em> attribute set. Edit or omit this line as needed. Here we also use <code>.phony_formatted()</code> to ensure that we follow E.164 protocol mentioned earlier.</p>
<p>Second, if you are sending from multiple phone lines there are some considerations to take into account. If you bought multiple lines because you need to get around international sending restrictions (see <strong>General Tips</strong>above), you will add logic here to handle that. These laws change all the time, so make sure you check Twilio’s <a target="_blank" href="https://support.twilio.com/hc/en-us/sections/205553288-International-Messaging">international messaging guidelines</a>to see what logic you need to add. Or, you may prefer to send your SMS through a phone line from the same country as the phone which will be receiving the text.</p>
<p>For example, we could send from a Malaysian phone line (Malaysian lines currently in beta) when <a target="_blank" href="https://support.twilio.com/hc/en-us/articles/115007575647-Limitations-on-sending-SMS-to-mobile-numbers-in-Malaysia">sending to Malaysian numbers</a>, but otherwise send from a default US number.</p>
<p>For some countries (France and India, others), you will probably want to add a check to determine whether you are sending transactional emails (alerts, two-factor auth codes, etc.) or marketing emails and adjust your code accordingly, but for simplicity we won’t cover that logic here.</p>
<pre><code>**<span class="hljs-built_in">require</span>** <span class="hljs-string">'twilio-ruby'</span>
</code></pre><pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">Services</span>::<span class="hljs-title">Twilio</span>::<span class="hljs-title">SMS</span>** &lt; <span class="hljs-title">Services</span>::<span class="hljs-title">Twilio</span>  
  **<span class="hljs-title">def</span>** **<span class="hljs-title">send</span>**(<span class="hljs-title">options</span> </span>= {})  
    options.reverse_merge!({  
      :<span class="hljs-function"><span class="hljs-params">from</span> =&gt;</span> @<span class="hljs-keyword">from</span> || sending_number,  
      :<span class="hljs-function"><span class="hljs-params">to</span>   =&gt;</span> receiving_number,  
      :<span class="hljs-function"><span class="hljs-params">body</span> =&gt;</span> @body  
    })  
    @client.api.account.messages.create(options)  
  **end**  

  **def** **receiving_number**  
    **<span class="hljs-keyword">if</span>** @user.present? &amp;&amp; !@user.sms_number.blank?  
      # Example <span class="hljs-keyword">of</span> a phone number pulled <span class="hljs-keyword">from</span> a user model  
      @user.sms_number.phony_formatted(format: :international)  
    **<span class="hljs-keyword">else</span>**  
      @t_phone.phony_formatted(format: :international)  
    **end**  
  **end**  

  **def** **sending_number**  
    # Use one phone line <span class="hljs-keyword">for</span> US and UK sending, and the other <span class="hljs-keyword">for</span> int<span class="hljs-string">'l  
    # This method can be overriden in our user model when we call this service  
    sending_number = **if** receiving_number.**include**?('</span>+<span class="hljs-number">1</span><span class="hljs-string">') || receiving_number.**include**?('</span>+<span class="hljs-number">55</span><span class="hljs-string">')  
      ENV['</span>TWILIO_US_NUM<span class="hljs-string">']  
    **else**  
      ENV['</span>TWILIO_I8LN_NUM<span class="hljs-string">']  
    **end**  
  **end**  
**end**</span>
</code></pre><p>Now our service is looking pretty beefy.</p>
<p>That does it on our SMS sending. Now let’s take a look at the Twilio Phone Lookup API. Here again we inherit from the base Twilio service.</p>
<p><strong>Twilio Phone Lookup</strong></p>
<p>We will borrow from our Twilio base class again, but for this part of the API we don’t need to fire a <code>send()</code> method. Instead, we will define a <code>fetch()</code>method which will make a retrieval call to the Twilio API. I’ve also make the <code>send()</code> method an alias of <code>fetch()</code> so no confusion occurs as you expand on this code; some of you will prefer to alias the method to <code>search(input_number)</code> instead.</p>
<p>Note the <code>catch_twilio_404()</code> method. This <a target="_blank" href="https://www.bogotobogo.com/RubyOnRails/RubyOnRails_Blocks_and_Yield.php">block</a> is crucial because the Twilio API will return an error response (specifically a <code>Twilio::Rest::RestError</code> )if the phone lookup doesn’t find a match. Instead of returning a naked exception and possibly crashing our application with it, we catch any such error as soon as it occurs and return <code>false</code> instead. I recommend using a gem such as <a target="_blank" href="https://github.com/smartinez87/exception_notification">Exception Notification</a> or <a target="_blank" href="https://github.com/paper-trail-gem/paper_trail">Paper Trail</a> to log these errors when they occur.</p>
<pre><code># example = Services::Twilio::PhoneLookup.new(user: current_user)  
# example.lookup  
# example.search(<span class="hljs-string">'+11234567890'</span>)
</code></pre><pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">Services</span>::<span class="hljs-title">Twilio</span>::<span class="hljs-title">PhoneLookup</span>** &lt; <span class="hljs-title">Services</span>::<span class="hljs-title">Twilio</span>  
  # <span class="hljs-title">Use</span> <span class="hljs-title">this</span> <span class="hljs-title">is</span> <span class="hljs-title">you</span> <span class="hljs-title">are</span> <span class="hljs-title">pulling</span> <span class="hljs-title">your</span> <span class="hljs-title">phone</span> <span class="hljs-title">number</span> <span class="hljs-title">from</span> <span class="hljs-title">a</span> <span class="hljs-title">user</span> <span class="hljs-title">model</span>  
  **<span class="hljs-title">def</span>** **<span class="hljs-title">fetch</span>**  
    <span class="hljs-title">lookup_result</span> </span>= catch_twilio_404 **<span class="hljs-keyword">do</span>**  
      address_book(@user.two_factor_sms).fetch  
    **end**  
    # This will either resolve to <span class="hljs-literal">false</span> or to a Twilio API Lookup object.  
    lookup_result  
  **end**
</code></pre><pre><code> # Use <span class="hljs-built_in">this</span> to manually enter a number <span class="hljs-keyword">for</span> lookup  
  **def** **search**(input_number)  
    lookup_result = catch_twilio_404 **<span class="hljs-keyword">do</span>**  
      address_book(input_number).fetch  
    **end**  
    # This will either resolve to <span class="hljs-literal">false</span> or to a Twilio API Lookup object.  
    lookup_result  
  **end**
</code></pre><pre><code> # This is where we actually run the API call <span class="hljs-keyword">for</span> the lookup  
  **def** **address_book**(number_to_search)  
    @client.lookups.v1.phone_numbers(number_to_search)  
  **end**
</code></pre><pre><code> # Wrap <span class="hljs-built_in">this</span> block around our lookup <span class="hljs-keyword">in</span> order to  
  # ensure we don<span class="hljs-string">'t run any into errors in our application  
  **def** **catch_twilio_404**  
    **begin**  
      **yield**  
    **rescue** Twilio::REST::RestError =&gt; err  
      # Add error handling/notification/logging code here  
      # Then we return false instead of an exception  
      false  
    **end**  
  **end**</span>
</code></pre><pre><code> **def** **lookup**  
    fetch  
  **end**
</code></pre><pre><code> **def** **send**  
    fetch  
  **end**  
**end**
</code></pre><p><strong>Using the Phone Lookup In A User Model to Validate Numbers</strong></p>
<p>Again, rename the <code>two_factor_sms</code> attribute to whatever name you are working with in your model. This implementation requires the <a target="_blank" href="https://github.com/joost/phony_rails">phony_rails</a>gem.</p>
<pre><code>$ rails g migration AddTwoFactorToUsers two_factor_sms:**string** two_factor_enabled:**string**
</code></pre><pre><code># user.rb
</code></pre><pre><code># Callbacks  
<span class="hljs-attr">validates_plausible_phone</span> :two_factor_sms, <span class="hljs-attr">allow_blank</span>: <span class="hljs-literal">true</span>  
<span class="hljs-attr">phony_normalize</span> :two_factor_sms, <span class="hljs-attr">default_country_code</span>: <span class="hljs-string">'AU'</span>  
<span class="hljs-attr">validate</span> :valid_sms_number
</code></pre><pre><code># Custom callback - validates our phone number through Twilio  
**def** **valid_sms_number**  
  **<span class="hljs-keyword">if</span>** !Rails.env.test? &amp;&amp; **self**.two_factor_sms.present?      
    lookup = Services::Twilio::PhoneLookup.new(**self**)  
    **<span class="hljs-keyword">if</span>** lookup.send == <span class="hljs-literal">false</span>  
      errors.add(:two_factor_sms, <span class="hljs-string">'is not a valid phone number'</span>)  
    **end**  
  **end**  
**end**
</code></pre><h3 id="heading-test-suite">Test Suite</h3>
<p>Finally, let’s test our integration. To do this, we need some <a target="_blank" href="https://robots.thoughtbot.com/how-we-test-rails-applications">test doubles</a> which will emulate the functionality of calling the Twilio API itself. And so, we are going to create a <a target="_blank" href="https://www.ibm.com/developerworks/library/wa-mockrails/index.html">mock</a> object for our SMS and <a target="_blank" href="https://www.ibm.com/developerworks/library/wa-mockrails/index.html">stub</a> the API calls in our Phone Lookup service.</p>
<p>Here we are going to build off of <a target="_blank" href="https://robots.thoughtbot.com/testing-sms-interactions">Thoughtbot’s test implementation</a> of the Twilio service.</p>
<p><strong>Stubbing Our Phone Lookup</strong><br />By overriding most of the methods in the Twilio call chain to instead return <code>self</code>, we bypass the errors we would get if those methods actually ran in our test environment. This way we don’t have to make any changes to our application code to bypass that issue, like a begin/rescue to catch specific test mode errors or similar. We avoid a lot of messy code bloat this way.</p>
<pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">FakePhoneLookup</span>**  
  <span class="hljs-title">Carrier</span> </span>= Struct.new(:type, :name)
</code></pre><pre><code> SMS_LOOKUP_HASH = {  
    <span class="hljs-string">'+12815552134'</span> =&gt; Carrier.new(<span class="hljs-string">'mobile'</span>, <span class="hljs-string">'T-Mobile USA, Inc.'</span>),  
    <span class="hljs-string">'+18475552134'</span> =&gt; Carrier.new(<span class="hljs-string">'landline'</span>, <span class="hljs-string">'AT&amp;T'</span>)  
  }
</code></pre><pre><code> cattr_accessor :return_type, :lookups, :carrier, :numbers  
  **attr_accessor**  :fetch, :num
</code></pre><pre><code> **self**.lookups = []  
  **self**.numbers = []
</code></pre><pre><code> # def initialize(_account_sid, _auth_token)  
  #   self.carrier = nil  
  # end
</code></pre><pre><code> **def** **phone_numbers**  
    **self**  
  **end**
</code></pre><pre><code> **def** **v1**  
    **self**  
  **end**
</code></pre><pre><code> **def** **lookup**(num)  
    @fetch = <span class="hljs-literal">true</span>  
    <span class="hljs-literal">true</span>  
  **end**  
  **def** **lookup**(num, true_or_false = <span class="hljs-literal">true</span>)  
    true_or_false  
  **end**
</code></pre><pre><code> **def** **lookups**  
    **self**  
  **end**
</code></pre><pre><code> **def** **send**  
    <span class="hljs-literal">true</span>  
  **end**
</code></pre><pre><code> **def** **address_book**(sms)  
    **self**  
  **end**  
  **def** **phone_numbers**(sms)  
    **self**  
  **end**
</code></pre><pre><code> **def** **catch_twilio_404**  
    **<span class="hljs-keyword">yield</span>**  
  **end**
</code></pre><pre><code> **def** **client**  
    **self**  
  **end**
</code></pre><pre><code> **def** **num**  
    **self**.numbers.last  
  **end**
</code></pre><pre><code> **def** **account**  
    **self**  
  **end**
</code></pre><pre><code> **def** **sms**  
    **self**  
  **end**
</code></pre><pre><code> **def** **api**  
    **self**  
  **end**
</code></pre><pre><code> **def** **messages**  
    **self**  
  **end**  
**end**
</code></pre><p><strong>Mock SMS Messages</strong></p>
<pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">FakeSMS</span>**  
  <span class="hljs-title">SmsMessage</span> </span>= Struct.new(:<span class="hljs-keyword">from</span>, :to, :body)
</code></pre><pre><code> cattr_accessor :messages  
  **self**.messages = []
</code></pre><pre><code> **def** **initialize**(_account_sid, _auth_token)  
  **end**
</code></pre><pre><code> **def** **num**  
    messages[<span class="hljs-number">-1</span>].to  
  **end**
</code></pre><pre><code> **def** **account**  
    **self**  
  **end**
</code></pre><pre><code> **def** **sms**  
    **self**  
  **end**
</code></pre><pre><code> **def** **lookups**  
    FakePhoneLookup.new  
  **end**
</code></pre><pre><code> **def** **api**  
    **self**  
  **end**
</code></pre><pre><code> **def** **messages**  
    **self**  
  **end**
</code></pre><pre><code> **def** **create**(<span class="hljs-keyword">from</span>:, to:, body:)  
    **self**.**<span class="hljs-class"><span class="hljs-keyword">class</span>**.<span class="hljs-title">messages</span> &lt;&lt; <span class="hljs-title">SmsMessage</span>.<span class="hljs-title">new</span>(<span class="hljs-title">from</span>, <span class="hljs-title">to</span>, <span class="hljs-title">body</span>)  
  **<span class="hljs-title">end</span>**  
**<span class="hljs-title">end</span>**</span>
</code></pre><p><strong>Adding Our Test Doubles to The Test Suite</strong></p>
<p>Add something like to following to your Rspec configuration.</p>
<pre><code># spec_helper.rb  
RSpec.configure **<span class="hljs-keyword">do</span>** |config|  
  config.before(:each) **<span class="hljs-keyword">do</span>** |example|  
    Services::Twilio.client_adapter = FakeSMS  
    <span class="hljs-attr">Services</span>::Twilio::SMS.client_adapter = FakeSMS
</code></pre><pre><code> Services::Twilio::PhoneLookup.stubs(:fetch).returns(<span class="hljs-literal">true</span>)  
    <span class="hljs-attr">Services</span>::Twilio::PhoneLookup.stubs(:lookup).returns(<span class="hljs-literal">true</span>)  
    <span class="hljs-attr">Services</span>::Twilio::PhoneLookup.stubs(:send).returns(<span class="hljs-literal">true</span>)
</code></pre><pre><code> **end**
</code></pre><pre><code> config.after(:each) **<span class="hljs-keyword">do</span>**  
    # Reset our mock messages after test finishes  
    FakeSMS.messages = []  
  **end**  
**end**
</code></pre><h3 id="heading-two-factor-authentication-using-one-time-passwords">Two-Factor Authentication Using One-Time Passwords</h3>
<p>Now that we have our model layer fully set up, let’s use our new services to power a two-factor authentication system.</p>
<p><strong>Adding One-Time Passwords and SMS methods to Our User Model</strong><br />Let’s add a simple <a target="_blank" href="https://github.com/mdp/rotp">ROTP</a> functionality to our user model. It’s not terribly hard to implement this ourselves, but let’s look at how we would do this using the <code>active_model_otp</code> gem.</p>
<p>To see another implementation of this gem, take a look at <a target="_blank" href="https://coderwall.com/p/qw7hwq/effortless-two-factor-authentication-in-rails">https://coderwall.com/p/qw7hwq/effortless-two-factor-authentication-in-rails</a>.</p>
<p>Here’s an implementation that will work for our purposes. Tweak to your needs.</p>
<p>Our migration:</p>
<pre><code>$ rails g migration AddOtpSecretKeyToUsers otp_secret_key:string
</code></pre><p><strong>User Model Additions:</strong></p>
<pre><code># user.rb  
has_one_time_password
</code></pre><pre><code>**def** **send_sms_auth**  
  **<span class="hljs-keyword">if</span>** **self**.two_factor? &amp;&amp; **self**.two_factor_keys_present?  
    receiving_number = **self**.sms_number.phony_formatted(format: :international)
</code></pre><pre><code> # You can override the Twilio service here  
    sending_number = ENV[<span class="hljs-string">'ALTERNATE_TWILIO_PHONE_NUMBER'</span>]
</code></pre><pre><code> **<span class="hljs-keyword">return</span>** Services::Twilio::SMS.new(**self**, {  
      <span class="hljs-attr">from</span>: sending_number, # optional  
      <span class="hljs-attr">to</span>: receiving_number,  
      <span class="hljs-attr">body</span>:  <span class="hljs-string">"Your code is #{**self**.otp_code}"</span>  
    }).send
</code></pre><pre><code> **<span class="hljs-keyword">else</span>**  
    **<span class="hljs-keyword">return</span>** <span class="hljs-literal">false</span>  
  **end**  
**end**
</code></pre><pre><code>**def** **sms_number**  
  **self**.two_factor_sms # || self.company.phone || whatever <span class="hljs-keyword">else</span>  
**end**
</code></pre><pre><code>**def** **set_sms**(sms)  
  enable_two_factor  
  **self**.two_factor_sms = sms  
  **self**.save  
**end**
</code></pre><pre><code>**def** **enable_two_factor**  
  **self**.two_factor_enabled = <span class="hljs-literal">true</span>  
**end**
</code></pre><pre><code>**def** **disable_two_factor**  
  **self**.two_factor_enabled = <span class="hljs-literal">false</span>  
**end**
</code></pre><pre><code>**def** **verify_sms_auth**(sms)  
  authenticate_otp_code(sms) || authenticate_otp(sms, <span class="hljs-attr">drift</span>: <span class="hljs-number">600</span>)  
**end**
</code></pre><pre><code>**def** **reset_one_time_password**  
  **self**.otp_code = <span class="hljs-number">6.</span>times.map{rand(<span class="hljs-number">10</span>)}.join # or whatever  
**end**
</code></pre><pre><code>**def** **set_one_time_password_secret**  
  # self.otp_regenerate_secret  
  **self**.otp_secret_key = ROTP::Base32.random_base32  
**end**
</code></pre><pre><code>**def** **ensure_has_one_time_password**  
  **self**.set_one_time_password_secret   **<span class="hljs-keyword">if</span>** **self**.otp_secret_key.blank?  
  **self**.reset_one_time_password        **<span class="hljs-keyword">if</span>** **self**.otp_code.blank?  
  **<span class="hljs-keyword">yield</span>**  
**end**
</code></pre><pre><code>**def** **valid_sms_number**  
  **<span class="hljs-keyword">if</span>** !Rails.env.test? &amp;&amp; **self**.two_factor? &amp;&amp; two_factor_sms_changed?  
    lookup = Services::Twilio::PhoneLookup.new(**self**)  
    **<span class="hljs-keyword">if</span>** lookup.send == <span class="hljs-literal">false</span>  
      errors.add(:two_factor_sms, <span class="hljs-string">'is not a valid phone number'</span>)  
    **end**  
  **end**  
**end**
</code></pre><pre><code>**def** **authenticate_otp_code**(otp)  
  otp == **self**.otp_code  
**end**
</code></pre><pre><code>**def** **authenticate_otp_secret**(otp)  
  otp == **self**.otp_secret_key  
**end**
</code></pre><p><strong>routes.rb</strong><br />Let’s add routes for our simple two-factor auth.</p>
<pre><code>match <span class="hljs-string">'/sms-auth'</span> =&gt; <span class="hljs-string">'twilio#send_sms_auth_code'</span>,  
      <span class="hljs-attr">as</span>: :send_sms_auth_code, <span class="hljs-attr">via</span>: [:post, :get]  
post <span class="hljs-string">'/sms-verify'</span> =&gt; <span class="hljs-string">'twilio#verify_sms_auth_code'</span>,  
      <span class="hljs-attr">as</span>: :verify_sms_auth_code
</code></pre><p><strong>Twilio Controller Spec</strong><br />Before we get to the controller addition, I wanted to show you how the spec would look in practice. Here it is, using our <code>FakeSMS</code> mock client.</p>
<pre><code><span class="hljs-built_in">require</span> <span class="hljs-string">'spec_helper'</span>
</code></pre><pre><code>**describe** TwilioController, **type**: :controller **<span class="hljs-keyword">do</span>**  
  <span class="hljs-keyword">let</span>(:sms_mock_client) { FakeSMS }  
  <span class="hljs-keyword">let</span>(:**user**) { FactoryBot.create(:**user**, {  
    <span class="hljs-attr">two_factor_sms</span>: <span class="hljs-string">'+12345678900'</span>,  
    <span class="hljs-attr">two_factor_enabled</span>: <span class="hljs-literal">true</span>  
  })}  
  subject { **user** }
</code></pre><pre><code> **describe** <span class="hljs-string">"[GET] send_sms_auth_code"</span> **<span class="hljs-keyword">do</span>**  
    it <span class="hljs-string">"redirects to form to enter code"</span> **<span class="hljs-keyword">do</span>**  
      **get** :send_sms_auth_code, **id**: user.id  
      expect(response.code).to eq <span class="hljs-string">'200'</span>  
    **end**
</code></pre><pre><code> it <span class="hljs-string">"doesn't accept user without two-factor enabled"</span> **<span class="hljs-keyword">do</span>**  
      user2 = FactoryBot.create(:**user**,  
        email: <span class="hljs-string">'abc@xyz.com'</span>,  
        <span class="hljs-attr">two_factor_enabled</span>: <span class="hljs-literal">false</span>  
      )  
      **get** :send_sms_auth_code, **id**: user2.id  
      expect(response).to redirect_to new_user_session_path  
    **end**  
  **end**
</code></pre><pre><code> **describe** <span class="hljs-string">'[POST] verify_sms_auth_code'</span> **<span class="hljs-keyword">do</span>**  
    it <span class="hljs-string">'signs in user with correct code'</span> **<span class="hljs-keyword">do</span>**  
      params = { **id**: user.id, <span class="hljs-attr">sms</span>: user.otp_code, <span class="hljs-attr">secret</span>: user.otp_secret_key }  
      <span class="hljs-attr">post</span> :verify_sms_auth_code, params  
      expect(response).to redirect_to messages_path  
    **end**  
    it <span class="hljs-string">'fails with incorrect sms'</span> **<span class="hljs-keyword">do</span>**  
      params = { **id**: user.id, <span class="hljs-attr">sms</span>: <span class="hljs-string">'111111'</span>, <span class="hljs-attr">secret</span>: user.otp_secret_key }  
      <span class="hljs-attr">post</span> :verify_sms_auth_code, params  
      expect(response).not_to redirect_to messages_path  
    **end**  
    it <span class="hljs-string">'fails with incorrect secret key'</span> **<span class="hljs-keyword">do</span>**  
      params = { **id**: user.id, <span class="hljs-attr">sms</span>: user.otp_code, <span class="hljs-attr">secret</span>: <span class="hljs-string">'1234321'</span> }  
      <span class="hljs-attr">post</span> :verify_sms_auth_code, params  
      expect(response).not_to redirect_to messages_path  
    **end**  
  **end**  
**end**
</code></pre><p><strong>Twilio Controller</strong><br />Now, let’s add our code to get those tests passing. We add our GET route to send out the code (yes I made it a GET Request, spew your criticism in the comments) and our POST route to verify the code.</p>
<pre><code>**<span class="hljs-class"><span class="hljs-keyword">class</span>** **<span class="hljs-title">TwilioController</span>** &lt; <span class="hljs-title">ApplicationController</span>  
  # <span class="hljs-title">GET</span> "/<span class="hljs-title">send</span>-<span class="hljs-title">sms</span>-<span class="hljs-title">auth</span>-<span class="hljs-title">code</span>"  
  **<span class="hljs-title">def</span>** **<span class="hljs-title">send_sms_auth_code</span>**  
    @<span class="hljs-title">user</span> </span>= resource_type.find(params[:id])
</code></pre><pre><code> **<span class="hljs-keyword">if</span>** @user.send_sms_auth  
      flash[:notice] = <span class="hljs-string">"SMS sent to #{@user.two_factor_sms}"</span>  
      # render :two_factor_form  
    **<span class="hljs-keyword">else</span>**  
      redirect_to new_user_session_path,  
        <span class="hljs-attr">notice</span>: <span class="hljs-string">"SMS not enabled for #{@user.email}"</span>  
    **end**  
  **end**
</code></pre><pre><code> # POST <span class="hljs-string">"/sms-verify"</span>  
  **def** **verify_sms_auth_code**  
    @user = resource_type.find(params[:id])  
    key_matches = params[:secret].present? &amp;&amp; @user.otp_secret_key == params[:secret]
</code></pre><pre><code> **<span class="hljs-keyword">if</span>** key_matches &amp;&amp; params[:sms].present? &amp;&amp; @user.verify_sms_auth(params[:sms])  
      sign_in(@user, <span class="hljs-attr">bypass</span>: <span class="hljs-literal">true</span>)  
      redirect_to after_sms_verification_path  
    **<span class="hljs-keyword">else</span>**  
      redirect_to new_user_session_path,  
        <span class="hljs-attr">notice</span>: <span class="hljs-string">'Failed authentication, please try again.'</span>  
    **end**  
  **end**
</code></pre><pre><code> protected
</code></pre><pre><code> **def** **admin?**  
    params[<span class="hljs-string">'admin'</span>] == <span class="hljs-literal">true</span> || params[<span class="hljs-string">'admin'</span>] == <span class="hljs-string">'true'</span>  
  **end**
</code></pre><pre><code> **def** **after_sms_verification_path**  
    admin? ? auth_users_path : messages_path  
  **end**
</code></pre><pre><code> **def** **resource_type**  
    admin? ? AdminUser : User  
  **end**  
**end**
</code></pre><h3 id="heading-making-our-tests-end-to-end">Making Our Tests End-to-End</h3>
<p><strong>Integration Spec</strong><br />You’ll need to tweak this to match your domain and environment and such, but this is a great addition to have in your test suite. The template goes like this:</p>
<pre><code># spec/integration/sms_spec.rb
</code></pre><pre><code>**<span class="hljs-built_in">require</span>** <span class="hljs-string">'spec_helper'</span>
</code></pre><pre><code>describe <span class="hljs-string">'SMS'</span>, <span class="hljs-attr">type</span>: :request **<span class="hljs-keyword">do</span>**  
  <span class="hljs-keyword">let</span>(:sms_mock_client) { FakeSMS }  
  <span class="hljs-keyword">let</span>(:user) { FactoryBot.create(:user, {  
    <span class="hljs-attr">two_factor_sms</span>: <span class="hljs-string">'+12345678900'</span>,  
    <span class="hljs-attr">two_factor_enabled</span>: <span class="hljs-literal">true</span>  
  })}  
  subject { sms_mock_client }
</code></pre><pre><code> describe <span class="hljs-string">'[POST] send_sms_auth_code'</span> **<span class="hljs-keyword">do</span>**
</code></pre><pre><code> it <span class="hljs-string">'sends a text message via the Twilio API after a notication is created'</span> **<span class="hljs-keyword">do</span>**  
      headers = {  
        <span class="hljs-string">"ACCEPT"</span> =&gt; <span class="hljs-string">"application/json"</span>,  
        <span class="hljs-string">'HTTP_REFERER'</span> =&gt; <span class="hljs-string">'http://example.com'</span>  
      }
</code></pre><pre><code> get <span class="hljs-string">"/sms-2fa/"</span>,  
      {  
        <span class="hljs-attr">id</span>: user.id,  
        <span class="hljs-attr">secret</span>: user.otp_secret_key  
      }, headers
</code></pre><pre><code> expect(subject.messages.count).to eq <span class="hljs-number">1</span>  
      expect(subject.messages[<span class="hljs-number">0</span>].from).to eq ENV[<span class="hljs-string">'TWILIO_NUM'</span>]  
      expect(subject.messages[<span class="hljs-number">0</span>].to).to eq <span class="hljs-string">'+12345678900'</span>  
      expect(subject.messages[<span class="hljs-number">0</span>].body).not_to be_nil  
    **end**  
  **end**  
**end**
</code></pre><p><strong>Feature Spec</strong><br />You’ll probably need to tweak this as well depending on how you set up your front end, but this test is extremely helpful to include as well.</p>
<pre><code><span class="hljs-built_in">require</span> <span class="hljs-string">'spec_helper'</span>
</code></pre><pre><code>feature <span class="hljs-string">'Two-Factor Auth'</span> **<span class="hljs-keyword">do</span>**  
  <span class="hljs-keyword">let</span>(:**user**) { FactoryBot.create(:**user**,  
    **password**: <span class="hljs-number">123456</span>,  
    <span class="hljs-attr">two_factor_sms</span>: <span class="hljs-string">'+14043548389'</span>,  
    <span class="hljs-attr">two_factor_enabled</span>: <span class="hljs-literal">true</span>  
  )}  
  <span class="hljs-keyword">let</span>(:**admin**) { FactoryBot.create(:admin_user,  
    **password**: <span class="hljs-string">'pass123456'</span>,  
    <span class="hljs-attr">two_factor_sms</span>: <span class="hljs-string">'+12344234495'</span>,  
    <span class="hljs-attr">two_factor_enabled</span>: <span class="hljs-literal">true</span>  
  )}
</code></pre><pre><code> scenario <span class="hljs-string">'Send one-time password code on default login'</span> **<span class="hljs-keyword">do</span>**  
    previous_sms_count = FakeSMS.messages.count
</code></pre><pre><code> visit(<span class="hljs-string">'/login'</span>)  
    fill_in <span class="hljs-string">'user_email'</span>, **<span class="hljs-keyword">with</span>**: user.email  
    fill_in <span class="hljs-string">'user_password'</span>, **<span class="hljs-keyword">with</span>**: <span class="hljs-string">'123456'</span>  
    click_button <span class="hljs-string">'Sign in'</span>
</code></pre><pre><code> page.should have_content(<span class="hljs-string">'SMS Authentication'</span>)
</code></pre><pre><code> expect(FakeSMS.messages.count).to eq previous_sms_count + <span class="hljs-number">1</span>
</code></pre><pre><code> fill_in <span class="hljs-string">'sms'</span>, **<span class="hljs-keyword">with</span>**: user.otp_code  
    click_button <span class="hljs-string">'Verify SMS code'</span>
</code></pre><pre><code> **within** <span class="hljs-string">'.site-navigation'</span> **<span class="hljs-keyword">do</span>**  
      page.should have_content(<span class="hljs-string">'Manage'</span>)  
    **end**  
  **end**
</code></pre><pre><code> scenario <span class="hljs-string">'Send one-time password code on admin login'</span> **<span class="hljs-keyword">do</span>**  
    previous_sms_count = FakeSMS.messages.count
</code></pre><pre><code> visit(<span class="hljs-string">'/2fa/login'</span>)  
    fill_in <span class="hljs-string">'admin_user_email'</span>,    **<span class="hljs-keyword">with</span>**: admin.email  
    fill_in <span class="hljs-string">'admin_user_password'</span>, **<span class="hljs-keyword">with</span>**: <span class="hljs-string">'pass123456'</span>  
    click_button <span class="hljs-string">'Login'</span>
</code></pre><pre><code> expect(page.title).not_to **include** <span class="hljs-string">'Login'</span>  
    page.should have_content(<span class="hljs-string">'SMS Authentication'</span>)  
    expect(FakeSMS.messages.count).to eq previous_sms_count + <span class="hljs-number">1</span>
</code></pre><pre><code> fill_in <span class="hljs-string">'sms'</span>, **<span class="hljs-keyword">with</span>**: admin.otp_code  
    click_button <span class="hljs-string">'Verify SMS code'</span>
</code></pre><pre><code> page.should have_content(<span class="hljs-string">'My Dashboard'</span>)  
    page.should have_content(admin.email)  
  **end**  
**end**
</code></pre><h3 id="heading-final-thoughts">Final Thoughts</h3>
<p>I hope that this helped you understand at least the gist of setting up Two-Factor Authentication in Rails. If you are able to set up a working implementation based on this, I’d love to hear from you with your thoughts. This was my first technical tutorial to go this far in-depth, please let me know if you need clarifications or help repeating this processing on your own application. More to come.</p>
]]></content:encoded></item></channel></rss>