Saturday, January 7, 2017

Install Centos on Parallels using Vagrant on OS X

It is helpful to have a local Centos Linux installation for development and testing.

Step-by-step guide

Note: run the following commands from a Terminal window.

Install Brew:
  1. Note: you might need to install the Xcode tools first, run Xcode, and accept the license agreement
  2. xcode-select –install
  3. ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Install Vagrant:
  1. brew cask install vagrant
  2. brew cask install vagrant-manager
Install Parallels Vagrant plugin:
  1. vagrant plugin install vagrant-parallels
Setup a directory for your Vagrant project:
  1. mkdir new_vagrant_project
  2. cd new_vagrant_project
Install Centos:
  1. vagrant init bento/centos-7.2
  2. vagrant up --provider parallels
SSH to your new VM:
  1. vagrant ssh
Resources:
  1. http://parallels.github.io/vagrant-parallels/docs/getting-started.html 
  2. http://www.howtogeek.com/211541/homebrew-for-os-x-easily-installs-desktop-apps-and-terminal-utilities/ 
  3. http://sourabhbajaj.com/mac-setup/Vagrant/README.html 
I hope that you found this helpful.  Now that you have it setup you can install whatever tools that you like such as Ansible, Java, etc...  Cheers.

Monday, August 15, 2016

Fun project for talk like a pirate day - a Pirate Slack bot!

(image source - wikipedia.com)

It's almost Internation Talk Like a Pirate day.  If you can believe that such a day exists...

In mid May some friends, Charley, Evan, another new fellow that we met named Josh, and I were at OSCON in Austin.  We participated in a hackathon one day there.

We only had one afternoon to write all of the code.  We utilized an existing npm / node.js package for a head start on the Slack bot.  Here is the Slackbot code - https://github.com/evansong/PirateBotKit .  It allows a user to type in "pirate hello" for example and the bot will output "ahoy".  https://github.com/evansong/PirateBotKit/blob/master/slack_pirate_bot.js has the majority of the Slack bot code.  You can check out the keys and values that we loaded into Redis here - https://github.com/evansong/PirateBotKit/blob/master/dictionary.js .

For the server side, Evan wanted to use Microsoft's WebAPI 2 REST APIs hosted in Azure along with Redis.  Here is the relatively simple REST API endpoints - https://github.com/evansong/PirateApi/blob/master/PirateApi/Controllers/PirateController.cs .

In the end, it was a fun experience to throw an application together in an afternoon.  The creator of Botkit was there and even checked out our app.

If you haven't participated in a hackathon yet I highly recommend it.  It's a great way to work on fun and interesting projects, meet new people, and work with new technologies.  Also, they are great for team building as well if you'd like to organize one for you and your colleagues.

Cheers.

Tuesday, April 26, 2016

Simple node.js app using YQL and Mailgun

YQL is a great and very responsive service for fetching JSON data.

Here's a simple example query.  The test button allows you to get a sample of the results and get a REST URL.

Here is some example code for fetching some ticker data.

// Get query results from Yahoo's YQL service
var request = require('request');
var fs = require('fs');

// # INSERT YOUR URLs HERE
var urls = [...];

// formatAsHtml - helper for formatting strings as simple HTML
var formatAsHtml = function (inputString, htmlTag) {
    switch (htmlTag) {
        case "b":
            formattedResult = "<b>" + inputString + "</b>";
            break;
        case "i":
            formattedResult = "<i>" + inputString + "</i>";
            break;
        case "h1":
            formattedResult = "<h1>" + inputString + "</h1>";
            break;
        case "h2":
            formattedResult = "<h2>" + inputString + "</h2>";
            break;
        case "h3":
            formattedResult = "<h3>" + inputString + "</h3>";
            break;
        case "hr":
            formattedResult = inputString + "<hr/>";
            break;
    }
    formattedResult += "<br/>";
 
    return formattedResult;
}

// logOrganizedResults - prep results for html file
var logOrganizedResults =  function (error, response, body) {
    if (!error && response.statusCode === 200) {
        console.log(formatAsHtml("Symbol " + response.body.query.results.quote.symbol,"b"));
        console.log("Name " + response.body.query.results.quote.Name);
        console.log(formatAsHtml("LastTradeWithTime " + response.body.query.results.quote.LastTradeWithTime, "i"));
        console.log(formatAsHtml("Change_PercentChange " + response.body.query.results.quote.Change_PercentChange,"b"));
        console.log("Volume " + response.body.query.results.quote.Volume);
        console.log("YearRange " + response.body.query.results.quote.YearRange);
        console.log("PercebtChangeFromYearHigh " + response.body.query.results.quote.PercebtChangeFromYearHigh);
        console.log("DaysHigh " + response.body.query.results.quote.DaysHigh);
        console.log("DaysLow " + response.body.query.results.quote.DaysLow);
        console.log(formatAsHtml("\r\n","hr"));
    } else {
        console.error(error);
    }
};

// Request data from Yahoo's YQL service
for (var i = 0; i < urls.length; i++) {
    request({url: urls[i], json: true}, logOrganizedResults);
}

You can name this node.js file as app.js or whatever you choose and run it as "node app.js > results.html" on Windows (*nix should be similar).

To send an email of the results you can do the following with the Mailgun API.

var Mailgun = require('mailgun-js');
var api_key = 'YOURKEYGOESHERE';
var domain = 'YOURDOMAINGOESHERE';
var from_who = 'YOURFROMEMAILGOESHERE';

var path = require("path");
var fp = [path.join(__dirname, 'results.html')];
var data = {
    from: from_who,
    to: "RECIPIENTGOESHERE",
    subject: 'SUBJECTGOESHERE',
    text: 'Your query results are attached.',
    attachment: fp
};

// submitEmailWithAttachment - sends email with attachment(s)
var submitEmailWithAttachment = function() {
    var mailgun = new Mailgun({apiKey: api_key, domain: domain});

    mailgun.messages().send(data, function (error, body) {
        if (error) {
            console.log('error', {error: error});
        }
        else {
            console.log("attachment sent", fp);
        }
    });
};

// Send email with the query results
submitEmailWithAttachment();

Then to put it all together, you can run it with a batch file (contents below), or a shell script on *nix.

del *.html
node app.js > results.html
node sendEmail.js

Alternatively, you could use the async npm module or some other flow control module.  Then you could host the node app in AWS Lamba, Azure, etc...  You could also improve the code a bit by refactoring and adding unit tests with Chai, or something similar.  Cheers.

P.S. The source is now on Github - https://github.com/kristianjaeger/StockDataEmailer .

Friday, October 16, 2015

AWS CloudFormation WaitCondition example

CloudFormation is a great tool for spinning up EC2 instances and the like.

Here is an example of using a wait condition for waiting until a Windows 2012 R2 Base service has started.  Please excuse the designer JSON.  I was using it to validate the JSON correctness.

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "YourInstanceId": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "DisableApiTermination": "false",
        "InstanceInitiatedShutdownBehavior": "stop",
        "ImageId": "ami-dfccd1ef",
        "KeyName": "YourKeyName",
        "Monitoring": "false",
        "Tags": [
          {
            "Key": "Name",
            "Value": "NameOfYourInstance"
          }
        ],
        "NetworkInterfaces": [
          {
            "DeleteOnTermination": "true",
            "DeviceIndex": 0,
            "SubnetId": "yourSubnetId",
            "GroupSet": [
              "yourSecurityGroupId"
            ],
            "AssociatePublicIpAddress": "true"
          }
        ],
"UserData": {
          "Fn::Base64": {
            "Fn::Join": [
              "",
              [
                "<powershell>\n",
                "Start-Service BITS \n",
"$arrService = Get-Service BITS \n",
"$returnCode = 1 \n",
"if ($arrService.Status -eq 'running'){ $returnCode = 0 } \n",
"while($arrService.Status -ne 'running') \n",
"{ \n",
"Start-Sleep -s 5 \n",
"$arrService = Get-Service BITS \n",
"if ($arrService.Status -eq 'running'){ $returnCode = 0 } \n",
"} \n",
                "cfn-signal.exe -e $returnCode ",
                {
                  "Fn::Base64": {
                    "Ref": "WaitHandle"
                  }
                },
                "\n",
                "</powershell> \n",
                "<persist>true</persist>"
              ]
            ]
          }
        }
      }
    },
    "WaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition",
      "DependsOn" : "instancei1c92e0da",
      "Properties": {
        "Handle" : { "Ref" : "WaitHandle" },
        "Timeout" : "300"
      },
      "Metadata": {
        "AWS::CloudFormation::Designer": {
          "id": "b0f248b8-89a7-4b6b-881a-ef79dd677322"
        }
      }
    },
    "WaitHandle": {
      "Type": "AWS::CloudFormation::WaitConditionHandle",
      "Properties": {},
      "Metadata": {
        "AWS::CloudFormation::Designer": {
          "id": "1f0d4b0b-1971-4e5d-9b2c-5472c764dc92"
        }
      }
    }
  },
  "Description": ""
}

The BITS service was used here since it's a built-in Windows service.  It could be whatever service that you would like to start and verify that it started.

CloudFormation seems good overall.  It would be nice to have a local validator for it and / or a way to test the templates locally first.

I'd like to explore the Vagrant AWS provider when I have time (heard that there might be bugs though regarding Windows).  Please feel free to comment and share your experiences.  Cheers.

Friday, October 9, 2015

WPF path data for plus and minus signs

WPF path data seems not so straight-forward when you first look at it.

There are tools out there to edit it though.

Here are some examples of plus and minus signs if you're interested in something for prototypes and the like.  I didn't see a lot on the web so I thought that I'd share.

Minus (used within a canvas):
            <Canvas.LayoutTransform>
                <RotateTransform Angle="90"></RotateTransform>
            </Canvas.LayoutTransform>
            <Path Width="25" Height="25" Stretch="Uniform" Fill="DarkGray"
            Data="M0,0 L8,0 L8,47 L0,47 z"

Plus (again used within a canvas):
            <Path Width="25" Height="25" Stretch="Uniform" Fill="DarkGray"
            Data="M3.875,0 L5.125,0 5.125,3.875 9,3.875 9,5.125 5.125,5.125 5.125,9 3.875,9 3.875,5.125 0,5.125 0,3.875 3.875,3.875 3.875,0 z"

Cheers.

Sunday, January 18, 2015

Enhance your Web API 2 project's security using the Microsoft AntiXssEncoder

It's fairly straight-forward to add anti-XSS security to your Web API 2 project.  You might be wondering why you would though.  Out of the box, Web API 2 does not automatically encode and decode for you.

There is a potential problem in that the web API project could be receiving untrusted input from a HTML5 and JavaScript client.  If that input gets persisted, or displayed elsewhere, and then displayed later you could have persistant XSS on your hands.

The solution is fairly simple though believe it or not.

1) Nuget packages can be installed for use with the Web API project's models
 <package id="ASPNetWebAPIAntiXss" version="1.0.0" targetFramework="net45" />
  <package id="ASPNetWebAPIRequestValidator" version="1.0.0" targetFramework="net45" />

2) An attribute can be added to the models for the first package above (uses the AntiXssEncoder under the covers)
Add this to models:
[AntiXss]

3) Next you need to secure data coming in via query string or posts other than models (query string data example here)

For Web.config:

<httpRuntime encoderType="System.Web.Security.AntiXss.AntiXssEncoder" />


==================

For WebApiConfig.cs (in Register)

            RequestValidator.Create<ValidationError>()
                .MapPropertyName(x => x.Property)
                .FlattenErrorMessages()
                .Map(x => x.Message).ToErrorMessage()
                .Init(config);

==================
Then create a class that extends ActionFilterAttribute and in OnActionExecuting add the following
            // Check query string data for XSS using Microsoft's AntiXssEncoder
            var queryStringDataForRequest = actionContext.Request.GetQueryNameValuePairs();

            if (QueryDataContainsXss(queryStringDataForRequest))
            {
                var response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, 
                    new HttpResponseException(new HttpResponseMessage()));
                actionContext.Response = response;
            }

It's up to you to define QueryDataContainsXss().  The simplest, and perhaps safest implementation is to compare the input to encoded input using the AntiXssEncoder with default settings.  If you find that they are not equal then break and return false.

Then you can add the attribute to the controllers.
Add this to controllers:
[AntiXssActionFilter]

It's a good idea to add tests for your implementation too.  RestSharp is an easy way to add REST client abilities to your tests.  I hope that this is helpful to others.  Cheers.

Kristian

Tuesday, November 25, 2014

Mocking controller context and route data for Web API controller (OAuth attribute)

ASP.NET Web API 2 is a great technology for creating RESTful web services.

However, there can be a challenge for unit testing if you need to mock the OAuth "Authorize" attribute on a controller's method.

This is where Moq comes in.  It's available here - https://github.com/Moq/moq4 .

So, say if you have a controller method that uses the OAuth "Authorization" attribute and it needs unit test coverage then you can use Moq to setup your test.

Example psuedocode for controller method:

[OAuthAuthorization]
public CustomData GetCoolData()
{
    // get data from route here
    // more business logic
    return CustomData object;
}

--------------

Example helper for setting up controller context and route data:
public HttpControllerContext SetupControllerContext(ApiController controller)
{
    controller.ControllerContext = // new one up here or call another helper to populate object
    controller.ControllerContext.Request = new HttpRequestMessage();
    controller.ControllerContext.Request.Headers.Add("Authorization", "Bearer fakeToken");
    controller.ControllerContext.RouteData = new HttpRouteData(new HttpRoute());
    // Add any key value pairs to route data here
    controller.ControllerContext.RouteData.Values.Add("key", valueObject);

    return controller.ControllerContext;
}


Example test code snippet:

// Arrange
_controller.ControllerContext = SetupControllerContext(_controller);
// Setup mock here to mock the data provider and return what you'd like or throw if negative test

// Act
var result = _controller.GetCoolData();

// Assert
Assert.IsNotNull(result);
// do any further validation

That's pretty much it.  There wasn't much online about how to do this so I wanted to share.  Cheers.