braytonium [brey-tohnee-uhm]: powering a sliver of life through code 2018-10-04T20:36:07.000Z http://braytonium.com/ Jeremy Brayton Hexo Laravel Passport Usage With Swaggervel v2.3 http://braytonium.com/2018/07/11/laravel-passport-usage-with-swaggervel-v2-3/ 2018-07-11T04:30:00.000Z 2018-10-04T20:36:07.000Z Overview

I've been using this Swaggervel package with almost all my recent Laravel projects.A few instances were lightly customized to work against different authentication schemes and I only briefly touched on using Laravel Passport.

I wanted to highlight a few areas while also offering up an example project as a lightly opinionated jumping off point.Just the highlights cover quite a bit of information but the example should have ample information in commit messages and in the finished product.

Setting up Laravel and Laravel Passport

First we run laravel new <project_name>, git init and commit immediately to mark our base Laravel installation.I've always preferred this immediate commit over making customizations first as it's far easier to track your customizations versus the base install.Next, we run through the Laravel Passport docs with the following caveats:

  • php artisan vendor:publish --tag=passport-migrations doesn't copy the migrations as expected. We manually do this.
  • php artisan migrate --step creates a migration batch for each migration file individually. This lets us rollback to individual steps ans is primarily personal preference.
  • app/Providers/AuthServiceProvider contains the following:

    1
    2
    3
    4
    5
    6
    7
    8
    Passport::routes(function (RouteRegistrar $routeRegistrar) {
    $routeRegistrar->all();
    });
    Passport::tokensCan([
    ]);
    Passport::enableImplicitGrant();
    Passport::tokensExpireIn(Carbon::now()->addDays(15));
    Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
  • Run artisan make:auth to utilize the app layout and create a home view that is protected by the Login prompt.

    • The Passport Vue components could be displayed on the welcome page but we're attempting to set future users up for better practices.
  • Create a proper WelcomeController with matching view that utilizes the same app layout
    • This is not necessary but this one step makes it possible to properly utilize artisan route:cache in the future as route closures aren't supported.

Setting up Swaggervel

Now that the basics are complete, we bring in Swaggervel via composer require appointer/swaggervel --dev.We can ignore the line in the documentation that mentions adding Appointer\Swaggervel\SwaggervelServiceProvider::class as that's only for Laravel versions earlier than 5.5 without package discovery.It's necessary to run artisan vendor:publish to publish the content as we're using this package as a dev dependency and the assets won't show up otherwise.Now that Swaggervel is in place we can bring it all together.

To start, we create the file app/Http/Controllers/Api/v1/Controller.php as our generic API base controller.This controller houses our root-level @SWG\Info definition in a convenient location.This also sets us up for future work where API controllers are versioned, though this is personal preference.The secret sauce is the @SWG\SecurityScheme annotation:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @SWG\SecurityScheme(
* securityDefinition="passport-swaggervel_auth",
* description="OAuth2 grant provided by Laravel Passport",
* type="oauth2",
* authorizationUrl="/oauth/authorize",
* tokenUrl="/oauth/token",
* flow="accessCode",
* scopes={
* *
* }
* ),
*/

The securityDefinition property is arbitrary but needs to be included in every protected route definition.You can specify multiple security schemes to cover things like an generic api key or likely multiple OAuth flows, though I haven't tried working out the latter.These are the supported flows and it's important to note that Swaggervel is currently on the OpenAPI 2.0 specification, though this may change in the future.The scopes specified includes everything (*) but we could define any scopes explicitly.It should be noted that we also need to setup the route definitions in our resource Controller classes but due to the verbosity they are too much to include in this post.A small snippet that is unique to working with this setup is the following:

1
2
3
4
5
*   security={
* {
* "passport-swaggervel_auth": {"*"}
* }
* },

This tells a specific endpoint to use the securityDefinition created earlier and it's important that these match.The example project has rudimentary UserController, User model, and UserRequest definitions that should be a decent starting point, though I can't vouch for them being very comprehensive.

Configuring our OAuth Client

First we need to create an OAuth client specifically for Swaggervel connections.Go to the /home endpoint and under OAuth Clients click Create New Client.Under Name specify Laravel Passport Swaggervel or just Swaggervel.Under Redirect URL we're unable to specify /vendor/swaggervel/oauth2-redirect.html directly, so use a placeholder like https://passport-swaggervel.test/vendor/swaggervel/oauth2-redirect.html instead.Using your SQL toolbox of choice, navigate to the table oauth_clients and look for the row with the name specified in the previous step, in our case Laravel Passport Swaggervel.Manually update the redirect column to /vendor/swaggervel/oauth2-redirect.html.

Now that our OAuth client in Passport should be setup correctly, we focus our attention on the config/swaggervel.php settings.The client-id should be set to what Passport shows in the UI as the Client ID field.This is also the id of the row in the oauth_clients table.The client-secret should be set to the what Passport shows in the UI as the Secret field.We also set both secure-protocol and init-o-auth to true, the latter of which fills in the UI with our secrets otherwise we'd have to put them in manually.

Correcting Swagger UI to Capture Tokens

For the OAuth2 redirect to function properly we need to modify the Swagger UI configuration in resources/views/vendor/swaggervel/index.blade.php.Under const ui = SwaggerUIBundle({ right below the url parameter should be oauth2RedirectUrl: '/vendor/swaggervel/oauth2-redirect.html',.This reinforcement is necessary as the Swagger UI doesn't 'catch' the tokens properly without this.Other notable additions that make the UI slightly easier to work with:

1
2
3
4
tagsSorter: 'alpha',
operationsSorter: 'alpha',
docExpansion: 'list',
filter: true

Testing Authentication via the Swagger UI

First we go to the api/docs endpoint to display the Swagger UI.Click the Authorize button with the unlocked padlock icon.Verify the client_id and client_secret sections are filled in.Click Authorize and the Laravel Passport screen labelled Authorization Request should display with the Authorize and Cancel buttons.Click Authorize again and you should be redirected back to Swagger with the client_id and client_secret now showing as ****** with a Logout button instead of Authorize.We should now be able to click on the GET /users route, click the Try it out button, click on the blue Execute button and be greeted with our expected response as a list of users.

Conclusion

We've hopefully highlighted the basic touch points of the process with the example code going into much further detail.The project is lightly opinionated to facilitate practices that have served me well so far.It is by no means a complete reference but it should be a good jumping off point when it's somewhat harder to see the big picture without a comprehensive example.

In case you need the link to the project again.

]]>
<h4 id="Overview"><a href="#Overview" class="headerlink" title="Overview"></a>Overview</h4><p>I&#39;ve been using <a href="https://github.co
Scratching an Itch With Prometheus http://braytonium.com/2018/07/06/scratching-an-itch-with-prometheus/ 2018-07-06T07:30:00.000Z 2018-10-04T20:36:07.000Z Not too long ago I became obsessed with Prometheus.I'd heard about it for a while, knew it was powerful, and couldn't quite understand how everything fit together.The documentation is extremely verbose for good reason but it took playing with it for a while for everything to click.This post is a rather concise and extensive overview that goes a long way in expressing the basic concepts to my developer brain.In their simplest form, exporters expose an HTTP endpoint of /metrics with the output being statistics in Prometheus' format.The real power of Prometheus comes when you expose your own /metrics endpoint and have Prometheus consume the statistics you generate.This post is also a very good introduction with the section Building your own exporter being extremely valuable in describing just some of the possibilities.

After getting my bearings I started with a prototype with a simple premise "Why look at the usage graphs in Digital Ocean for each server independently? Why not have it in one location?"How To Install Prometheus on Ubuntu 16.04 is a very good primer to get everything up and running quickly.

I've made a few modifications since working through the article:

  • Prometheus version 2.3.1
    • There have been massive perf improvements in v2.3.x.
  • node_exporter version 0.16.0
    • There are significant changes to the metrics naming conventions.
    • This exporter typically has the most coupling with Grafana dashboards and often requires altering them to work correctly.
  • Use prometheus:prometheus for ownership of core prometheus processes like prometheus or alertmanager.
    • sudo useradd --no-create-home --shell /bin/false prometheus
  • Use prometheus-exporter:prometheus-exporter for ownership of exporters. Exporters should possibly be more isolated but I feel it may be a case of YAGNI.
    • sudo useradd --no-create-home --shell /bin/false prometheus-exporter
  • Set scrape_interval to 1 minute: scrape_interval: 1m.
    • 15 seconds is still doable but I'm currently not concerned with very granular detail.
    • This reduces the load of making 4 calls per minute to just 1, reducing some overhead required for Prometheus and every exporter.

At $dayJob we've moved to provisioning servers using Laravel Forge, which has the possibility of utilizing exporters for mysqld, mariadb, postgres, memcached, redis, beanstalkd, nginx, php-fpm, and sendmail.I've opted to use node_exporter, mysqld, nginx-vts-exporter, php-fpm, and redis respectively.To put the original premise into perspective, replicating the newer monitoring agent graphs in Digital Ocean only require node_exporter.A few of the exporters require very little setup, only setting a few configuration variables systemd service definitions. Other exporters like nginx-vts-exporter require building nginx from source.

I plan to introduce a series of posts that should aid in getting a very rudimentary implementation running.There is an abundant usage of Kubernetes in the Prometheus ecosystem, to the point that it almost seems required but fortunately it also just works(tm) in a traditional virtual machine without any real fuss.

]]>
<p>Not too long ago I became obsessed with Prometheus. I&#39;d heard about it for a while, knew it was powerful, and couldn&#39;t quite unde
Code School Transition Woes http://braytonium.com/2018/07/02/code-school-transition-woes/ 2018-07-02T07:30:00.000Z 2018-10-04T20:36:07.000Z In this blog post on January 26 2015, Code School became part of Pluralsight.The website codeschool.com continued to operate normally until earlier this year when a banner showed the site would shut down and transition to Pluralsight June 1st.The banner pointed to this url, which gives a great overview of the changes but was sparse on what would take place during the transition.

It wasn't until June 1st that I finally understood the full breadth of the transition and stumbled upon the integreation faqs.The important bit of information is this snippet:

Will I be able to access my Code School invoices or course history?

No. Your invoices and course history will not carry over or be accessible as of 6/1.

Code School customers were instructed to generate a PDF of their profile before the migration.Due to finding the integration FAQs after June 1st, sadly I wasn't able to do that in time.

What particularly impacts me the most is a belief that pointing potential employers to a reputible website as a source of truth carries far more weight than a PDF that can be altered.As a web developer in an industry where employers seem to assume a resume is partially or wholly embellished, this seems like a step backwards.

In spite of the transition pains, I do find Pluralsight's Skill IQ to be a fresh way to measure competency with multiple choice questions that cover broad aspects of a given topic.You're shown what is marked wrong so you can learn from your mistake and the equivalent of the old Code School subscription I believe allows unlimited retests.The integration with Stack Overflow's developer story is compelling enough to use it and I did gain quite a sense of accomplishment when I scored in the very low expert level range.

As I finished typing this up I noticed Pluralsight seems to have a fair number of the Code School courses by searching for the keyword "Code School".There are newer interactive courses like the one titled HTML 5 and CSS 3: Overview of Tag, Attribute and Selector Additions but the introductory video includes the Front End Formations title that it was called on Code School.It appears that some of the content is migrating over but things aren't 1:1 so we may never get credit for courses we've essentially completed.I plan on going through the course shortly as I hope at least the challenges have been updated but it would be a terrible experience to go through all of this realizing I've accomplished it recently.

I don't quite know how I feel about the transition a month in and now after noticing at least some of the content was moved over.It's hard to lose the accomplishments but the outcome would've been no different if Code School closed completely.It does have me pause to make sure the course accomplishments I share are worth the investment and that's likely an important thing to remember whenever similar services catch my attention.

]]>
<p>In <a href="https://www.pluralsight.com/blog/news/code-school-acquisition" target="_blank" rel="noopener">this blog post</a> on January 2
Laravel Passport Displays Basic Authentication Prompt http://braytonium.com/2017/09/27/laravel-passport-displays-basic-authentication-prompt/ 2017-09-27T14:00:00.000Z 2018-10-04T20:36:07.000Z

I've been bitten by this issue so many times that I have a form of amnesia where I forget that it happenedall over again. This github issue highlights the problembut I'm more of a visual learner.

The problem can be traced back to configuring the redirect_uri parameter incorrectly. OAuth2 highlyrequires that the callbacks are identical between the server and consumer(s). For consumers that areexternal to the app, this is almost never a problem. For first-party consumers like Swagger(vel), this isextremely easy to configure incorrectly.

]]>
<img src="/images/posts/2017/09/Passport_prompt.png" width="450" height="250" title="Laravel Passport prompt"> <p>I&#39;ve been bitten by th
Revisiting Laravel Homestead MySQL Password Expiration http://braytonium.com/2017/01/08/revisiting-laravel-homestead-mysql-password-expiration/ 2017-01-08T20:00:00.000Z 2018-10-04T20:36:07.000Z After putting the solution in my previous post through its paces for a few weeks, I realized the less intrusive approach is to patch Homestead v2's scripts/create-mysql.sh with the following snippet:
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env bash

cat > /etc/mysql/conf.d/password_expiration.cnf << EOF
[mysqld]
default_password_lifetime = 0
EOF

service mysql restart

DB=$1;

mysql -e "CREATE DATABASE IF NOT EXISTS \`$DB\` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci";

This change pipes the default_password_lifetime setting into the file /etc/mysql/conf.d/password_expiration.cnf and restarts the mysql service. The provisioning process then can proceed as normal.

This approach requires no updated vagrant virtualbox image or other similar adjustments and allows us to keep using version 0.3.3 indefinitely.

I'm likely going to abandon my settler and homestead forks as I couldn't adequately maintain them moving forward. I'll work to push this upstream as I feel it should be implemented there.

]]>
<p>After putting the solution in <a href="/2017/01/07/addressing-laravel-homestead-mysql-password-expiration/">my previous post</a> through
Addressing Laravel Homestead MySQL Password Expiration http://braytonium.com/2017/01/08/addressing-laravel-homestead-mysql-password-expiration/ 2017-01-08T01:00:00.000Z 2018-10-04T20:36:07.000Z On November 7th 2016, I was hit with a peculiar issue I've never seen before working in a provisioned Homestead box. The exception:
1
2
PDOException in Connector.php line 55:
SQLSTATE[HY000] [1862] Your password has expired. To log in you must change it using a client that supports expired passwords.

Firing up a different vagrant machine, I was greeted with the same problem. This seemed to affect all of the vagrant boxes using version laravel/homestead (virtualbox, 0.3.3).

On the machine, the MySQL version displayed by mysql --version is

1
mysql  Ver 14.14 Distrib 5.7.9, for Linux (x86_64) using  EditLine wrapper

MySQL 5.7's password expiration policy seemed to point to the culprit.

1
2
3
From MySQL 5.7.4 to 5.7.10, the default default_password_lifetime value is 360 (passwords must be changed approximately once per year). For 
those versions, be aware that, if you make no changes to the default_password_lifetime variable or to individual user accounts, all user
passwords will expire after 360 days, and all user accounts will start running in restricted mode when this happens.

Looking at the list of users with relevant columns shown that the password for the user homestead was set on 2015-11-13 03:50:18.

1
2
3
4
5
6
7
8
9
10
11
mysql> select host, user, authentication_string, password_expired, password_last_changed, password_lifetime from mysql.user;
+-----------+-----------+-------------------------------------------+------------------+-----------------------+-------------------+
| host | user | authentication_string | password_expired | password_last_changed | password_lifetime |
+-----------+-----------+-------------------------------------------+------------------+-----------------------+-------------------+
| localhost | root | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | N | 2016-11-08 22:28:11 | NULL |
| localhost | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | N | 2015-11-13 03:50:10 | NULL |
| 0.0.0.0 | root | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | N | 2015-11-13 03:50:15 | NULL |
| 0.0.0.0 | homestead | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | N | 2015-11-13 03:50:18 | NULL |
| % | homestead | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | N | 2015-11-13 03:50:18 | NULL |
+-----------+-----------+-------------------------------------------+------------------+-----------------------+-------------------+
5 rows in set (0.00 sec)

Date manipulation in PHP showed that 360 days from 2015-11-13 03:50:18 is 2016-11-07 03:50:18, about the time this started occurring.

It was later that I discovered this pull request didn't make it into branch revert-56-master used to build the 0.3.3 box. It succinctly described the problem at hand.

I saw 4 possible choices for a permanent solution:

  1. Set default_password_lifetime=0 explicitly in /etc/mysql/my.cnf.
  2. Upgrade MySQL to 5.7.11 or higher as the default was changed from 360 to 0.
  3. Create the homestead user with the keywords PASSWORD EXPIRE NEVER to disable password expiration for that user.
  4. All of the above.

Solution

In looking to correct upstream, the pull request was denied with very good reason. It was a ton of work to seemingly get the 5.6 branch up to master and I have absolutely no guarantee that something wasn't broken in the process.

Not being content with abandoning that work, I pushed a vagrant virtualbox image that should continue the 5.6 branch forward for the foreseeable future. There is one major caveat, it requires a patch to Homestead v2 to accommodate the changes introduced.

Steps required to use the image:

  1. Add the new vagrant image: vagrant box add w0rd-driven/homestead.
  2. Add the line box: "w0rd-driven/homestead" in Homestead.yaml to specify a different vagrant box than the default of laravel/homestead.
  3. Add the line "laravel/homestead": "2.0.x-dev" to the require-dev section of composer.json.
  4. Add or update the repositories section of composer.json:

    1
    2
    3
    4
    5
    6
    "repositories": [
    {
    "type": "git",
    "url": "https://github.com/w0rd-driven/homestead.git"
    }
    ],
  5. Run composer update to change to the new composer package.

  6. Rebuild your box using vagrant destroy -f then vagrant up.
  7. Test everything.

I've enabled issues on both forks of settler and homestead. Unfortunately, I don't have VMWare Fusion to build the vmware provider image. If anyone has the capabilities, I would gladly grant the access to push the image.

]]>
<p>On November 7th 2016, I was hit with a peculiar issue I&#39;ve never seen before working in a provisioned Homestead box. The exception:
Windows 10 Mobile ~14295 Downgrade http://braytonium.com/2016/04/18/windows-10-mobile-14295-downgrade/ 2016-04-18T00:00:00.000Z 2018-10-04T20:36:07.000Z In the event this causes grief in the future I wanted to point out the steps to downgrade Windows 10 Mobile build 14295 back to 8.1. The Windows Device Recovery Tool fails to detect the phone without the steps outlined in BrunoTrivellato's response on page 2.

To make this easier, I thought I would repurpose the steps as I can't seem to find an independent or direct link:

  1. Unplug the phone from the PC
  2. Click on "My device was not detected"
  3. Select your model and you will enter the "Searching Screen"
  4. Reboot your phone (pressing volume down + home button for some seconds until it vibrates) and immediately plug it back in the PC
    • If you take too long to plug it in the PC you will have to reboot it again (the Recovery Tool will show a message to you)
  5. The tool will recognize your model, but not the OS or Firmware
  6. Click in "Download Software" and wait the process to complete.
  7. When finished, click next and check your Battery as the screen says
  8. The next screen will try to install the software BUT IT WILL FAIL, don't worry it is normal. Wait (3-4 minutes) until it fails and click Finish.
  9. Repeat steps 1-5.
  10. Now you will see that the screen will not show "Download" but "Install", click it.
  11. You will see the installation progress both in the Tool and in your Phone. Wait until it finishes (2-3 minutes).
]]>
<p>In the event this causes grief in the future I wanted to point out the steps to downgrade Windows 10 Mobile build 14295 back to 8.1. The
JSON Resume http://braytonium.com/2016/04/17/jsonresume/ 2016-04-17T23:00:00.000Z 2018-10-04T20:36:07.000Z I wanted to mark what feels like an oasis in the desert of a long journey. During my last job search over 2 years ago, I tired of what had become a disjointed resume update routine. Accomplish a task, go to the Word-document-as-one-true-source, update, print to PDF, go to LinkedIn, update, go to careers.stackoverflow.com, update, rinse & repeat.

I yearned for one interchangeable format that allowed me to generate HTML, Word and PDF at the very least. JSON Resume combined with resume-linkedin seemed like a great fit. Unfortunately, due to recent LinkedIn API changes resume-linkedin was all but useless. My first contribution was born out of the realization that if you could get the LinkedIn data through the API console, the process still worked, albeit extremely cumbersome.

As I worked on migrating this site to my personal forkof a theme in Hexo, I thought a custom JSON Resume theme would also be a good fit. These changes to my resume can be found here or here.

]]>
<p>I wanted to mark what feels like an oasis in the desert of a long journey. During my last job search over 2 years ago, I tired of what h
Newness http://braytonium.com/2016/01/13/newness/ 2016-01-13T06:00:00.000Z 2018-10-04T20:36:07.000Z I said in my previous post that a lot can happen in 2 years.

In that time span I've:

  • Moved to using a MacBook and OSX.
    • OSX being very BSD-like makes it an prime target for web development. It isn't the second class citizen Windows is in the Ruby or Node.js communities.
  • Transitioned away from .NET and don't really miss it. I do randomly play around with .NET core when possible but I haven't actually built anything with it.
    • This was honestly very huge at the time but I still feel I made the right decision. Though Windows 10 is the platform Windows 8 should have been and likely would've kept me on board.
  • Transitioned to PHP and web technologies full bore. I'm no fan of the PHP language but in the era of Visual Studio 2012, a dynamic language that only required refreshing my browser was much faster than waiting on the compile cycle.
  • Drank the vagrant koolaid via PuPHPet.
    • Recreating production hardware isn't too difficult with my ancient DevOps experience.
    • Waiting on the painful commit/push/wait for deployment/refresh cycle to see a change was a huge productivity destroyer.
    • Even developing locally when production PHP versions aren't consistent can be a nightmare. Something like rvm in Ruby comes close but it isn't perfect.
  • Immediately took to PHPStorm as my IDE of choice. JetBrains have done an amazing job and if you've used ReSharper you've only had a taste. I'm no fan of Java but I'll make a concession for tools this good.
  • Wrote a very crude front-end only CMS. When working in only HTML, CSS, and Javascript you really see the separation of client and server very clearly.
  • I jumped in the deep end with tools like gulp, bower and yeoman.
    • This has fueled my desire to be a lot more fluent in Node.js.
    • Frontend development becomes insanely fun because a lot of the tedium melts away if you do it right.
    • This gulp template was extended from this blog post and it's subsequent repository to streamline working on the custom CMS.
    • This yeoman gulp generator looks a little more promising as it seems to serve a similar purpose but feels like less work.
  • I have a Microsoft Lumia 640 and the Windows 10 Mobile OS is one of the best mobile experiences I've used to date. I know I'm biased but it has shaped up really well.
  • My personal laptop is running Windows 10 as well so I haven't abandoned the Windows ecosystem by a long shot, I've just become more of a consumer rather than a developer.

That's really only scratching the surface. It would've been helpful to have blog posts as I moved along but as with most things, life got in the way.

My main goal for the early part of 2016 is to revamp this site and make it the playground I was looking for in 2013. Octopress is really nice but if I upgrade to v3 it's not much more work to migrating away to something like Hexo, Metalsmith, or DocPad.

]]>
<p>I said in my <a href="/2016/01/10/we-be-derpin/">previous post</a> that a lot can happen in 2 years.</p> <p>In that time span I&#39;ve:</
We Be Derpin' http://braytonium.com/2016/01/11/we-be-derpin/ 2016-01-11T06:00:00.000Z 2018-10-04T20:36:07.000Z A lot can happen in a little over 2 years...

In my last post, I had proposed an attempt to tackle the FizzBuzz problem. PowerShell was done, PHP was barely started but I never pointed to it in a subsequent post or finished what I wanted. The project url has completed and checked solutions for PHP and Node.js. I had mentioned b. F#, Objective-C, CoffeeScript, C/C++, Go, Dart, and Haskell are the planned languages I've mostly touched in passing or know about., as well as C#, Pascal, and Ruby but I may never get to them.

Shortly after that last post, I switched jobs from .NET to web development focusing on PHP with HTML, CSS, and Javascript. That one action shifted much of my focus from most of the languages in that list. With ES6 coming and recently finishing a CodeSchool course in CoffeeScript, the Javascript landscape is looking pretty awesome. Elixir and the Phoenix Framework have recently stood out as upcoming contenders for my mindshare as well.

My last post taught me that while I may know of a language, it doesn't mean I'll have a genuine desire to pursue it. It can also easily become difficult to want to pursue development outside of your day job. Staying current, however, is always worth pursuing. Tooling and efficiency around web development seems to have come a very long way.

To keep this post brief, I plan on making more updates as I feel a lot has changed for me in the past 2 years that I'd still love to share.

]]>
<p>A lot can happen in a little over 2 years...</p> <p>In my <a href="/2013/11/05/jazzhands-tackling-the-fizzbuzz-problem/">last post</a>, I
JazzHands: Tackling the FizzBuzz Problem http://braytonium.com/2013/11/06/jazzhands-tackling-the-fizzbuzz-problem/ 2013-11-06T07:30:00.000Z 2018-10-04T20:36:07.000Z Due to a comment on Hacker News (original post here), I thought I would put my money where my mouth was, so to speak, and tackle this problem in a public repository.

My comment could likely be seen as dismissive or arrogant. I get that. My biggest problem is that because people still fail, this is the interview equivalent of patty cake: awkward, childish, and unrewarding (unless you're a 2 year old).
To be quite honest, I don't quite understand my disdain for the problem. It's simple enough that it can be solved a number of ways quickly and gets you to express at least the fundamentals of development in a particular language.

This exercise is an excellent opportunity for a number of things:

  1. It'll be a form of code kata and I need practice, even on something I dislike greatly.
  2. Much of my work isn't public, as I often rarely see the benefit of my specific ideas being shared. I don't need to prove anything by doing this but I don't see this hurting anything.
  3. If you believe my time tracking is accurate, it should demonstrate at least some proficiency in languages I know and how quickly I can at least have a basic understanding of the ones I don't. a. My proficiency in order is C#, PowerShell, Javascript, PHP, Pascal, then Ruby. The latter 3 don't rattle around in my brain as much as the former. b. F#, Objective-C, CoffeeScript, C/C++, Go, Dart, and Haskell are the planned languages I've mostly touched in passing or know about.
  4. This would be a good opportunity to write tests to check the work. A neutral 3rd party would be ideal as the tests could influence the experiment.
  5. It'll also give insight into my habits regarding structure and clean, concise code. I prefer readable code with very little comments because I feel the code itself should be the comment. This largely isn't possible in most code bases but it shouldn't really be a problem here.
  6. To prove to myself that I don't just take examples from Google and make them my own, that I can start from scratch when I need to.

Note: I'm using http://rosettacode.org/wiki/FizzBuzz as a language guide only. If you see me follow a specific example, punch me in the nuts.

The best description of the problem can be found here, specifically (altered for this example):

Write a program that prints the numbers from 1 to 100. But for multiples of three print "Jazz" instead of the number and for the multiples of five print "Hands". For numbers which are multiples of both three and five print "JazzHands".

This brings up some excellent points. I'm definitely not above FizzBuzz or live coding but I still can't pinpoint why I have beef with this particular problem.

I honestly can't remember the last time I've actually tackled this problem so the potential to look really foolish, at least at the beginning, is pretty high.

]]>
<p>Due to a <a href="https://news.ycombinator.com/item?id=6623198" target="_blank" rel="noopener">comment on Hacker News</a> (original post
Notable Octopress Tweaks: Copyright, Tags, & Feed Excerpts http://braytonium.com/2013/10/28/notable-octopress-tweaks-copright/ 2013-10-28T17:00:00.000Z 2018-10-04T20:36:07.000Z Copyright

This is almost pointless to mention but the standard templates give you a very specific copyright with respect to atom feeds (Copyright (c) x-y). The file source_includes\custom\footer.html includes a way of gathering the system time in the form:

1
2
3

Copyright &copy; {{ site.time | date: "%Y" }}

I simply replaced the current hard-coded year with the ruby code above so that when the site is generated, it always gives the current year.

In case any of you are wondering how to insert codeblocks with liquid syntax, see this post.

Tags

This is more involved but luckily gist makes it stupid simple to include here. Everything is pretty much a rip off of the category_generator plugin and includes with just minor tweaks to use the tag object.

_config.yml:

plugins/tag_generator.rb (an almost complete copy of category_generator.rb)

source/_includes/archive_post_tags.html

source/_includes/custom/tag_feed.xml

source/_includes/post/tags.html

source/_layouts/tag_index.html

Feed excerpts

The following goes on line 23 in my atom.xml file, or right before the content tag. A better alternative would be to detect an excerpt and only display that or the content, not both.

1
2
3

{% if post.has_excerpt %}<summary type="html">{{ post.excerpt | xml_escape }}</summary>{% endif %}

]]>
<h2 id="Copyright"><a href="#Copyright" class="headerlink" title="Copyright"></a>Copyright</h2><p>This is almost pointless to mention but th
Derpirc: WP7 IRC Client Take #2 http://braytonium.com/2013/10/28/derpirc-wp7-irc-client-take-2/ 2013-10-28T08:30:00.000Z 2018-10-04T20:36:07.000Z Back in February of 2011, I posted a very rough alpha release of my first WP7 IRC app called dIRCa. I abandoned the project primarily due to the heavy reliance on Homebrew sockets and rewrote it from scratch using the wonderful IrcDotNet library. Not having to handle the core IRC quirks is a godsend and luckily it works rather flawlessly with 7.5+ (Mango and above).

I originally wrote a post back in 2011 to gather emails for the beta submission process but it never got published. I was also working diligently to release a competent v1.0 but my perfectionism got the best of me.

I've since release it as open source on Github. The project is abandoned so far as my HD7 phone is no longer consistently in use now that I've switched to the HTC 8x and Windows Phone 8.

The barriers to make it a Windows Phone 8/WinRT version are pretty high:

  1. SQL CE was a terrible choice as a message store. They ditched it in favor of SQLite which had extremely sketchy WP7 support (this means a complete break from WP7)
  2. IrcDotNet is very much a traditional .NET library where the developer focuses on Mono. You could say this project is abandoned as well, so no official WinRT port is expected.

The original project received quite a bit of downloads for my first open source project (around 700 by this time) with the reason primarily being that a XAP was already built. On Github there are no releases but I look to remedy that very shortly.

The application is pretty functional but it is rather rough around the edges. For instance, when you first start it you're required to go to the settings screen as exiting initializes and starts the connections to the various networks. I intended this to be covered in a tutorial of sorts but that was something I was going to cover off last.

]]>
<p>Back in February of 2011, I posted a very rough alpha release of my first WP7 IRC app called <a href="/2011/02/20/wp7-irc-client-dirca/">
Octopress Site Generation on Windows 8.1 http://braytonium.com/2013/10/25/octopress-on-windows-8.1/ 2013-10-25T03:00:00.000Z 2018-10-04T20:36:07.000Z Install RailsInstaller from here. I use the version with Rails 3.2.

libcurl

  • Download the latest "Win32 - Generic" libcurl with SSL development release from here (this is the last entry as of 10/23/2013).
  • Unpack the zip file.
  • Copy curl.exe, libcurl.dll and libidn-11.dll to C:\RailsInstaller\bin.
    The reason I copy curl to test the program. It verifies the files are in the expected path and has an added bonus of making sure all the dll dependencies are present. This is how I figured out libidn-11.dll was necessary to include.

SSL certificate setup

  • Download cacert.pem.
  • Place file in C:\RailsInstaller\cacert.pem.
  • Set an Environment Variable in Control Panel with the Variable name: SSL_CERT_FILE and Variable value: C:\RailsInstaller\cacert.pem.
  • To temporarily set the variable for this command prompt session, use set SSL_CERT_FILE=C:\RailsInstaller\cacert.pem.
]]>
<p>Install RailsInstaller from <a href="http://railsinstaller.org/" target="_blank" rel="noopener">here</a>. I use the version with Rails 3.
My Blog's Notable Octopress Tweaks http://braytonium.com/2013/07/11/my-blogs-notable-octopress-tweaks/ 2013-07-11T17:00:00.000Z 2018-10-04T20:36:07.000Z My plan is for this post to serve as an index to the upcoming posts. Unlike the ASP.NET MVC posts that fizzled (sorry), I need to chronicle these changes in the event I need to dissect them again.

Here's the collection in no particular order:

  • Copyright date - This one is simple and almost not worth noting. I use a copyright date range of "[start year]-[current year]" and this post simply explains the what and why.
  • Tag generator - Octopress will not support tags. Tag index pages are trivial to implement but I'm also starting to agree with the premise that one taxonomy should really be enough.
  • Feed excerpts - These aren't generally created to my knowledge, or specifically the summary section. The general way to create excerpts is a little awkward but smart.
  • Google Form notification full service sample taken from here.
  • (Upcoming) Category & Tag index generators for the primary /categories/ /tags/ directory. WordPress didn't have this either but it would be a good idea to list all of them in one place.

One thing in the FAQ that particularly bit me during the WordPress conversion was Using Non-ASCII Characters In Your Blog. Most conversion posts cover this but I'm in the habit of always having this as part of my environment just in case.

The primary reason for my approach so far was to be a close representation as possible of the WordPress site to combat 301 redirect woes. Tags will eventually disappear I think but I like the exercise of making sure they're around in full. The platform seems to support "something" so it's fun to see how far I can go with it.

]]>
<p>My plan is for this post to serve as an index to the upcoming posts. Unlike the ASP.NET MVC posts that fizzled (sorry), I need to chronic
Migration From WordPress to Octopress Complete http://braytonium.com/2013/07/10/migration-from-wordpress-to-octopress-complete/ 2013-07-10T21:00:00.000Z 2018-10-04T20:36:07.000Z In case anyone was watching, I switched the blog from a generic WordPress with a slightly customized theme to octopress. I'm using the excellent Octoflat theme with a few notable tweaks. I reintroduced the search and feed buttons as well as expanded the navigation to allow nested menus. The theme allows for nested menu elements and while 2 levels deep is highly acceptable, I happen to use 3.

I'm writing this post using the excellent MarkPad which serves all of my needs perfectly. You don't need a markdown editor, but having one with live-preview that reinforces the markdown syntax is killer. That I can insert a URL and it automatically format the document accordingly is a small but useful touch.

I plan on posting the various tweaks that make up this blog. While there aren't a ton, I think a few of the concepts are worth expanding on. I don't claim these tweaks are original by any means but I found a lot of ideas needed to be fleshed out a little more to be acceptable for my tastes. Yes, I'm anal.

I expect nothing but great things from this migration though it took roughly a month of quite a few tinker sessions to get things where I wanted it. I blame using Ruby on Windows to be a big culprit but also my n00bness got in the way in some areas. It also took me quite a bit to grok how deployments functioned but now that everything gels, I don't expect any issues.

The site will continue to be a slight work in progress as I button up some of the loose ends. I have a few design tweaks in mind and I'm looking to expand my portfolio with more current projects. Not everything I've done in the past 2 years can be seen unfortunately but there's quite a body of work piling up, waiting to be shown.

]]>
<p>In case anyone was watching, I switched the blog from a generic WordPress with a slightly customized theme to <a href="http://octopress.o
Shadow Copies on XP, Robocopy, PowerShell V2 http://braytonium.com/2012/05/02/shadow-copies-on-xp-robocopy-powershell-v2/ 2012-05-02T04:31:12.000Z 2018-10-04T20:36:07.000Z [I forgot to post this draft back in April 2010. Needless to say I no longer utilize the technique nor can really help now that it's purged from my memory]

I've cobbled together a poor-man's backup solution using PowerShell and robocopy in what I thought was a somewhat resilient solution. Robocopy turned out to be a poor choice based upon my needs and nitpicks but I wanted to outline why to save myself and others a little pain.

Strike 1:

This URL describes the bug and relative fix: http://superuser.com/questions/48303/access-denied-error-with-robocopy-as-admin. While using /ZB and /B helps it wasn't solving the problem because the relevant ACLs weren't being created even as late as Windows 7.

Strike 2:

robocopy has 3 (relevant) major versions: 2003 Resource Kit (the one I was using 010), Vista/RoboCopy GUI (026), and Windows 7. To make things more complicated, installing RoboCopy GUI on a 2003/XP machine will put robocopy under %windir%system32 which happens to enumerate after the 2003 Resource Kit path. This means you have to explicitly call system32robocopy or rename the resource kit version if you hope to keep the other resource kit tools.

Strike 3:

I erroneously thought by adding users to the Backup Operators group, a requirement to use the /B switch, robocopy was creating local shadow copies. I might have been confusing it with HoboCopy and figured taking a shadow copy snapshot before a robocopy operation would fix the problem. Turns out taking all that time, determining you almost always need to be administrative, and XP's limited ability to easily expose a snapshot as a drive letter/share made this become an incredible deal breaker.

Temporary solution:

To combat the bug that started this investigation, I initially tried using version 026 of robocopy to no avail. I used every combination of /copyall, /copy:dats, /copy:dt or just /copy:d.

What really fixes the problem is to completely obliterate the destination folder(s) and start over. This would correctly build the relative ACL and prevent the access denied message but it would only be a matter of time until it happened again.

My permanent solution:

  1. Steal Steve Murawski's great Invoke-SyncFrameworkSample code outlined here. (download link at the bottom)
  2. Install Sync Framework 2.0 Runtime.
  3. Modify code to use 1 or 2-way sync (default sample is 2-way).
  4. Modify code to enumerate the FileReport object and build a slightly more robocopy-like output.
  5. Modify code to create DestinationPath*. If it isn't found it doesn't make sense to do a 2-way sync either.
  6. ???
  7. Do not profit. The bulk of the code isn't mine :(

Note: Robocopy is an end-to-end solution whereas I have far more flexibility to shoot myself in the face with this PowerShell script and the Sync Framework in general.
*: This technique negates the solution completely because I'm creating these directories under the user context the script is run in.

Shadow copies aren't used so to run this in a limited user context I still need the user in the Backup Operators group. I will likely work up a solution using shadow copies on the server as I can rather painlessly manipulate them using WMI. AlphaVSS behaves much better if you are not using Windows XP too.

]]>
<p><em><strong>[I forgot to post this draft back in April 2010. Needless to say I no longer utilize the technique nor can really help now th
Dotfuscator on WP7 Hurdle: Re-Signing Assemblies http://braytonium.com/2011/11/17/dotfuscator-on-wp7-hurdle-re-signing-assemblies/ 2011-11-17T03:00:07.000Z 2018-10-04T20:36:07.000Z I've started toying with the proper Dotfuscator project settings to give me a workable, yet relatively-secure-as-possible package for deploying to private beta testers and the Marketplace. A great starting point for this journey could be found here: http://weblogs.asp.net/bsimser/archive/2010/12/31/dotfuscator-deep-dive-with-wp7.aspx.

Before we start, my project includes a number of 3rd party controls like AppBarUtils, MVVMLight, Funq, and my favorite IrcDotNet (which is the source of this post). The instructions say to use your XAP file as input so we'll follow that. On the far right-hand side of the Input Files toolbar is Transform XAML/BAML resources in all assemblies. Click this to turn it off primarily to be thorough. I believe this affects MVVM because it tries to rename Xaml internals that are data bound. Follow the instructions on the Settings->Global Options screen to set Disable Control Flow and Disable Renaming to No to enable them.

Now click the Build Project toolbar button to build your project. If your XAP includes a signed assembly, you'll be greeted with the following message:

Warning: The strong named input assemblies (or assembly) <TempDirectory>IrcDotNet.dll were not resigned. You will need to sign these dotfuscated assemblies manually.

My first instinct was to go to the Settings->Signing screen, and enable Re-sign Strong Named Assemblies and point it to IrcDotNet.snk. If you do that you're met with a different message:

Signing Assemblies...Running sn.exe /q /R <ConfigDirectory>IrcDotNet.dll <Location of>IrcDotNet.snkWarning: Password protected Strong Name files are not supportedsn returned 1.Build Error.

This is the end of the line as far as automation goes. The only recourse is to sign the assembly manually as the original warning states. If you do not resign this file before deployment, your app will not startup properly. Once code hits that signed assembly it simply will not function.

My first approach was to go to the Rename and Control Flow tabs and exclude every assembly other than my own. This produces the same result. Assemblies are reassembled regardless of whether or not any options are applied.

My preferred approach is to go to the Input tab, right click on each 3rd party assembly and click Exclude assembly from package. This has a lovely UI effect of removing everything from the screen and pausing while Dotfuscator works its magic. The added bonus? This happens every assembly. The bare minimum would be to only remove those signed assemblies but I took it all the way and removed all 3rd party dlls. These are all open source frameworks so obfuscating them isn't necessary.

Now click Build Project again and the app starts! Inspecting the result in IL Spy gives me a runtime error on decompile, meaning control flow is on and teh IP iz protectordez. My app also uses localization and Smart Obfuscation automatically disables renaming for my localization resources so no extra legwork is needed to exclude them.

In summary if you don't need to obfuscate 3rd party assemblies, simply exclude them from the Input tab rather than trying to exclude them in the individual obfuscation tabs. Ilasm is still ran on the assemblies which triggers the need to re-sign them.

]]>
<p>I&#39;ve started toying with the proper Dotfuscator project settings to give me a workable, yet relatively-secure-as-possible package for
Avenged Sevenfold - Nightmare -> Severe Badassery http://braytonium.com/2011/05/29/avenged-sevenfold-nightmare-severe-badassery/ 2011-05-29T01:28:28.000Z 2018-10-04T20:36:07.000Z I promised a post on kind of breaking down how I understand the album but I thought a combination of it could make me pretentiously douchie and who really cares? Well I do.

I figured I'd try to post this as I listen to the album, giving notes on each track. One thing kind of goes without saying that this is The Rev's last studio work before his death and much of that echoes through each track to me. It's going to be very weird hearing an A7V track without him physically on the drums. Not that I hated any of the other albums mind you, but this is perhaps his best work too which makes it even more tragic to me. I literally can't listen to it without going "Aww damnit!" every time I remember.

I won't try to dissect what I think each track means I don't think. That seems a little pretentious because people often have their own interpretation anyway. Now that I've bored you and the title track Nightmare is over I can go over it:

1 Nightmare - The opening track starts out really mellow which A7V can do quite well but when hell hits around the 0:30 second mark it instantly becomes a typical track. Dueling squeals of guitars and drums of steel quickly start the crescendo to the first verse. The solo sections aren't too over done and when the drums come back, I can't help but start head banging. This is a strong opening for me, really.

2 Welcome to the Family - I have to admit now that I've stopped playing the entire album full stop, I tend to skip this one. This is a track I'd love to play on Rock Band just for the random complexity in spots. As I listen to it I can't really put why I don't like it to words but I think I just pine for the other tracks.

3 Danger Line - I confess I did skip the last track. Danger Line starts with a sweet snare bit that just keeps me interested immediately. I said I wouldn't describe the meaning of tracks but this one seems pretty straightforward and I'll admit it's part of what hooks me. It doesn't hurt that during the verse there's a badass low riff leading to more dueling fills. What really gets me, and sets off that response someone had a name for is right around 3:15 when the piano starts (Hi, Rev! :(). Once the last words are spoken and the guitars come back, I not only identify with the person the track describes but The Rev as well. It's partly eerie how well it works and how deep it can go without personally knowing these people.

4 Buried Alive - Starting off with a lovely ditty to immediately follow the last track, I get sucked in like a black hole. I might not some of these tracks on their own but the order was pure mastery except for one caveat*. There's not much I can say other than it's just all good and especially around the 5:00 mark when the beat changes. Much head banging ensues.

5 Natural Born Killer - Starts off strong with a nice fast tempo. I tend to not like this track like #2 for unknown reasons. I suppose the correct phrasing would be "like less" because I could listen to all of the tracks quite easily but others have a lot of gravity if the metaphor holds.

6 So Far Away - I suppose the only thing I can really say is the words are eerie in the context of everything but right about 3:40 when the slowness starts it ramps up in awesome for me. Belting out "Soooo far awaaaaay" really makes the words hit even harder.

7 God Hates Us - As a Christian I can't say I enjoy the lyrics at all, which tends to lead me to skip it. Yeah I know, such a Bible thumping behavior but I suppose part if it reminds me of the times I did "hate God" which only reminds me of how drastically my view to cause such hatred was altered. I don't believe God hates anything but that's neither here nor there.

8 Victim - It's hard to describe any special parts of the track though I listen to it consistently with everything else. It's a solid yet basic A7V track to me.

9 Tonight The World Dies - I actually have to skip this track consistently. When he sings a long "Iiiiiiiiiiii" somehow that note just pierces my brain and I want it out of my head immediately. I'm listening to it to the point where that starts, which is right around 1:40. Ugh skip time.

10 Fiction - By far far far far my favorite track. I suppose it's The Rev's badass piano work in addition to the drum beat. The entire thing is just ear sex to me. I'm being sonically "fucked gently" as it were. Ending on the organ as they do just seals the entire package for me. I can't really explain it other than "mmmmmmm mmmmmmmm, bitch!"

11 Save Me - Welcome to my second favorite track and only because of the fucking awesome intro. This is the way to end a metal album to me and again goes back to placement. I'd really love to play this on Rock Band. Being a 10 minute song though would be Freebird quality almost but I suppose I can't get over how awesome the song is in spite of this. To that end it almost gets too excessive but it never steps over that boundary. "Tonight we all die young" does explain things quite well and since that's my last lyric paste I can promise I won't make any more.

*- The caveat is the last two tracks are so badass I'd rather listen to them earlier but it does end with a huge bang.

So there you have it. I personally think it's a badass album and I'd almost listen to tracks 10 and 11 first but any new album always gets a straight 1-n pass as many times as I can stand it so I can determine which tracks I skip. This album has almost 0 especially if I just wanted to be lazy. This is Avenged Sevenfold to me and every album has grown to be better than the last for me. It's quite sad that I'll miss The Rev though, especially having never seeing them live yet.

]]>
<p>I promised a post on kind of breaking down how I understand the album but I thought a combination of it could make me pretentiously douch
WP7 IRC Client -> dIRca http://braytonium.com/2011/02/20/wp7-irc-client-dirca/ 2011-02-20T12:43:54.000Z 2018-10-04T20:36:07.000Z I chose a cheesy name to spoof on one of my favorite films lately, Team America: World Police. The project likely wouldn't exist if it wasn't for the pioneering efforts of Jeremiah Morrill on the XDA forums. I used the Homebrew project, built by daveux here. The primary reason I chose it was a more 1:1 with the System.Net namespace to use one project for both Windows and Windows Phone (or Silverlight or whatever until the Portable Library Projects bake into VS 2010 SP1).

I'm in the process of determining if I want to use CodePlex or BitBucket and I'm really torn. Bitbucket has awesome small features like merging usernames and a slightly better issue tracker (2 extra fields whee) with external services support as well like being able to track things via Google Analytics. I may just release to both initially just to see which gets picked up or used more often but that may bite me in the ass.

As of today the app works connecting to the very first server created in the settings factory. The very first thing I want to get done after this is use real settings stored in isolated storage and build the UI to change it. I'd like to do that before taking off the reigns and publishing for real but I'll see how that goes.

I could try to explain the UI but screenshots would serve a better purpose of landscape and portait mode respectively:

I'm using the excellent Chillen font, one I've dubbed the new Comic Sans so we'll see how long that sticks. At least initially I hope to have multiple servers as pages with their own pivot controls for channel and query messages. DCC and CTCP commands aren't supported at all and I don't really parse channel events yet except topic changes but things are slowly coming together now that the networking infrastructure is somewhat stable.

I am looking for testers but there's some pretty big caveats. You need developer sideloading access to your phone, either through ChevronWP7 or normal marketplace unlock. I do not have any clue what will happen to this codebase after NoDo hits but I believe native support should still be possible. That puts me in a rush to try to finish something to at least incubate as people use it and luckily I could work on a WPF/SL port reusing almost all of the code.

I primarily posted this just to have a place to link to those screenshots for posterity since I couldn't seem to figure out how to store local images in codeplex or bitbucket. My n00bness is showing...

]]>
<p>I chose a cheesy name to spoof on one of my favorite films lately, Team America: World Police. The project likely wouldn&#39;t exist if i