Skip to contentSkip to author details

featured

A 7-post collection

Why I undeleted my Facebook account

Written by Michael Earls
 EXIF  facebook  featured  privacy

OK, I lasted a few days anyway. I decided to undelete my Facebook account before it was too late. However, I tightened my security and privacy settings so that I would not get Friend requests from complete strangers.

I decided to undelete the account because there is no better way to keep in touch with distant friends and relatives than Facebook. I am already “in the system” (as my friend Sean has pointed out), so it doesn’t matter what I do from this point forward.

I was also wrong about the photo data that is stored. Facebook strips the EXIF data from photos (I’m not sure if they store the images with the EXIF data intact and then strip it when you view the image, or if they strip it when you upload it). Here is an article concerning the privacy of Photo data.

Also, here is the privacy tab on Facebook that you can use to set some limits.

.Net - Creating a generic extension of "Contains" to see if there's something in a generic collection

Written by Michael Earls
 .NET  C#  DTO  Extension Methods  featured  Generics

Update: Added reference links at bottom of entry.

I was working with some code today and needed to see if a list of custom DTOs contained an object based on a string value I had. Here is my solution.

Some background…

Our Architecture uses a base abstract class called DtoBase:

public abstract class DtoBase { public string Id { get; set; } public string Description { get; set; } public DtoBase() { } public string ToJson() { StringWriter w = new StringWriter(); JsonSerializer s = new JsonSerializer(); s.Serialize(new JsonTextWriter(w), this); return w.ToString(); } }

All classes that derive from DtoBase have their own properties, but they all benefit from Json serialization using the ToJson method. This helps us in various ways in the application.

I am working with a generic list of a subclass of DtoBase (AccessoryGroup):

public class AccessoryGroup : DtoBase { public bool QCFlag { get; set; } }

With this list, I wanted to see if it contained a DTO with an ID based on a given string. Unfortunately, the built-in Contains extension method on the list (in the System.Linq namespace) does not allow this behavior. It would require me to create an instance of AccessoryGroup containing the values I want to compare (and implement the IEquatable interface on DtoBase. No big deal, but another requirement). What I needed was a version of the Contains extension method that let me pass in a string.

So, my first attempt was to create my own extension method using List as the type to extend:

public static bool Contains(this List list, string val) { foreach(DtoBase dto in list) { if dto.Id val.Trim() { return true; } } return false; }

Aside from the use of the foreach (which I refactored in the final code), this code did not work.

Here is some test code:

List accessoryGroupList = new List(); accessoryGroupList.Add(new AccessoryGroup { Id = "test", Description = "This is just test data" }); if(accessoryGroupList.Contains("test")) { // this should be true }

However, this code did not work. In fact, it didn’t even build. I got invalid arguments exceptions with my Contains call.

What to do? It then occurred to me that I’m working with a generic list, so I need to take a generic approach to this. Here’s the final code taht implements my new extension method as a generic method:

public static bool Contains(this List list, string val) where TDto : DtoBase { return list.Any(a => a.Id.Trim() val.Trim()); }

Not only have I refactored to remove the ugly foreach loop, but I’ve converted the method to a generic method.

I thought I was going to have to write my code like this:

List accessoryGroupList = new List(); accessoryGroupList.Add(new AccessoryGroup { Id = "test", Description = "This is just test data" }); if(accessoryGroupList.Contains("test")) { // this should be true }

But I did not. It seems that because the accessoryGroupList is already a generic list of AccessoryGroup DTOs, it automatically knows that the Contains method will use the same type. Nice, huh?

So, my original code worked:

List accessoryGroupList = new List(); accessoryGroupList.Add(new AccessoryGroup { Id = "test", Description = "This is just test data" }); if(accessoryGroupList.Contains("test")) { // this is true }

As you can see, using generics and extension methods has saved the day again. There is a lot of generic code in our architecture using the DtoBase class. This is just another example of why generics and extensions are so important.

Our server repositories that feed our REST API use the same DTOs that our portable class library containing our client libraries uses. Because of the shared class library, I can use this new extension method on the server or on the client.

References:

MSDN Extension methods guide
List.Contains() method

Basic Authentication with AngularJS and WebAPI Part 2 - The Angular Client

Written by Michael Earls
 AngularJS  ASP.NET  featured  security  WebAPI

Update: I’m an Angular newbie. I’ve learned a bit about Angular JS since this was written. As such, I don’t recommend using $scope as I did, I recommend using Controller as. I also believe that there may be a replacement for $broadcast, but I’m not sure.

Here is a great blog entry about some common Angular JS mistakes from Jeremy Likness.

In part 1, I linked to a few blog entries about getting Basic authentication to work with AngularJS. I outlined what was required to make the suggested idea work in ASP.NET WebAPI, but I didn’t detail what was required in the AngularJS client. The blog entries that I linked to were also very light on details, so I thought I’d put together this blog post to show an end-to-end solution for this problem.

This project is available on GitHub at https://github.com/cerkit/BasicAuthWebApiSample.git

I’m missing a few features that were intended to be included due to my newbie status with AngularJS. In particular, I do not currently have a way to save the failed requests for later to retry them after the user successfully logs in. That will probably have to wait until I get better with AngularJS. Also, there may be a better way to inject the credentials into the web request other than putting the code into the controller. I’ll try to improve on this model at a later date.

To start, let’s take a look at the .config for the app.

/*  
* $http interceptor. 
*
* On 401 response - it stores the request and broadcasts 'event:auth-loginRequired'. 
*/ 
angular.module('app').config(function ($httpProvider){  
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
var interceptor = ['$rootScope', '$q', function (scope, $q) {  
    function success(response) { return response; } 
    function error(response) { 
        var status = response.status; 
        if (status === 401) { 
            var deferred = $q.defer(); 
            var req = { 
                config: response.config, deferred: deferred 
        }; 
        //scope.requests401.push(req); 
        scope.$broadcast('event:auth-loginRequired'); 
        return deferred.promise; 
    } 
    // otherwise return $q.reject(response); 
    } 
    return function (promise) { 
            return promise.then(success, error); 
        } 
    }]; $httpProvider.responseInterceptors.push(interceptor); 
});

Notice that I add a header on line 7 that sends the XMLHttpRequest to the server. If you’ll remember from the last post, this will cause the server to send an “xBasic” authentication method, thereby bypassing the browser’s built-in security dialog. This will allow us to answer the 401 Unauthorized response with our own login dialog.

Here is the template for the login dialog:

<div class="modal h1">  
    <div class="h2 container alert-info modal-body" data-backdrop="static">                 
        Login <div class="alert-danger">{{error}}</div> 
        <ng-form class="form-horizontal"> 
        Username: <input class="form-control" ng-model="username" />                    
        Password: <input class="form-control" type="password" ng-model="password" /> 
        <button class="btn-default" ng-click="login(username, password)">Login</button> 
        </ng-form> 
     </div> 
</div>

This contains the modal class that the dialog requires to be a modal dialog. In order for the dialog to be opened, a request has to be made to an $http resource. This is done by the main controller, but the actual work is done by an $httpProvider interceptor. You can see the interceptor definition on lines 8-27 of the above code. Notice that when the status of a request is 401, it fires the auth-loginRequired event. This indicates that the dialog needs to be shown. This event is answered by a directive that then launches the dialog. Here is the directive:

angular.module('app').directive('loginDialog', function () {  
        return { 
            templateUrl: 'app/templates/loginDialog.html', 
            restrict: 'E', 
            replace: true, 
            controller: 'CredentialsController', 
            link: function (scope, element, attributes, controller){
                scope.$on('event:auth-loginRequired', 
                    function () { 
                        console.log('got login event');     
                        element.modal('show'); 
                    });  
                    scope.$on('event:auth-loginConfirmed',
                        function () { 
                            element.modal('hide');                            
                            scope.credentials.password = ''; 
                        }); 
            } 
        } 
    });

The CredentialsController performs the login:

function CredentialsController($scope, $http, $cookieStore, Base64) {  
        $scope.login = function (userName, password) { 
            var encodedUserNameAndPassword = Base64.encode(userName + ':' + password); 
            $http.defaults.headers.common['Authorization'] = 'Basic ' + encodedUserNameAndPassword; 
            $cookieStore.put('basicCredentials', encodedUserNameAndPassword);  
            $http.get(baseUrl + '/Values') 
                .success(function() { 
                    $scope.$broadcast('event:auth-loginConfirmed');  
                    $scope.password = ''; 
                }) 
                .error(function() { 
                    $scope.error = 'Invalid Login'; 
                }); 
        }; 
    };

Notice that the login method calls the event for auth-loginConfirmed. This will cause the modal dialog to be hidden. It is also answered by the SampleController so that it can refresh its data.

We’ll then see the login-dialog directive being used at the bottom our index.html page. This is there just so that we can respond to the event and show the dialog.

<html ng-app="app">  
    <title>Sample Angular Client for Basic Authentication</title> 
    <meta name="description" content=""> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
    <link rel="stylesheet" href="css/normalize.css"> 
    <link rel="stylesheet" href="css/main.css"> 
    <!-- Latest compiled and minified CSS for Bootstrap --> 
    <link href="css/bootstrap.min.css" rel="stylesheet" /> 
    <!-- Optional theme --> 
    <!--<link href="css/bootstrap-theme.min.css" rel="stylesheet" />--> 
    <link href="css/bootstrap.flatly.min.css" rel="stylesheet" /> 
    <script src="js/vendor/modernizr-2.6.2.min.js"></script> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.js"></script> 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js"></script>
    <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"></script>')</script>
    <script src="js/plugins.js"></script> 
    <script src="js/bootstrap.min.js"></script> 
    <script src="js/vendor/angular-resource.min.js"></script>
    <script src="js/vendor/angular-cookies.min.js"></script> 
    <script src="js/vendor/angular-timer.min.js"></script> 
    <script src="app/app.js"></script> 
    <script src="app/factories/base64-factory.js"></script> 
    <script src="app/controllers/controllers.js"></script>  
    <body ng-controller="SampleController"> 
        <div class="h2 label-info">{{currentUser | uppercase}}</div> 
        <ul> 
            <li ng-repeat="value in Model"> {{value}} </li> 
        </ul> 
        <button class="btn-default h2" ng-click="logout()">Logout</button>     
        <login-dialog />  

Since we’re using the SampleController, let’s take a look at what it does to get the data:

var baseUrl = 'http://localhost:49587/api';  
    angular.module('app').controller('SampleController', function ($scope, $http, $cookieStore, Base64) { 
        $scope.refreshData = function () { 
            //Used to display the data 
            if ($cookieStore.get('basicCredentials')) {
                $http.defaults.headers.common['Authorization'] = 'Basic ' + $cookieStore.get('basicCredentials'); 
            } 
            $http.get(baseUrl + '/Values')
                .success(function (data) { 
                    $scope.Model = data; 
                    $scope.loading = false; 
                    $scope.currentUser = Base64.decode($cookieStore.get('basicCredentials')).split(':')[0]; 
                }) 
                .error(function () { 
                   $scope.error = "An Error has occurred while loading data";
                   $scope.loading = false; 
                }); 
        } 
        $scope.loading = true; 
        $scope.refreshData(); 
        $scope.logout = function () {
            $cookieStore.remove('basicCredentials'); 
            $scope.currentUser = null; 
            $scope.Model = null; 
            $http.defaults.headers.common.Authorization = '';
            $scope.refreshData(); 
        } 
        $scope.updateValue = function (model) { 
            $http.put(baseUrl + '/Values', model); 
            window.setTimeout(function () { 
                $scope.refreshData() 
            }, 1000);  
        } 
        $scope.$on('event:auth-loginConfirmed', function () {
            $scope.refreshData(); 
        }); 
    });

The refreshData() function checks to see if there’s a credentials cookie. If so, it sends the credentials along in the Authorization header. This is the part that should be changed. I think it needs to go in the interceptor, but I haven’t quite figured out how to do it. After setting credentials, the controller has various functions for dealing with the data. It also sets the currentUser property on the scope so that it can be displayed on the home page.

This should illustrate the end-to-end process of enabling basic authentication on an AngularJS application when used with ASP.NET WebAPI.

I’ve been very happy with the results. Just make sure you secure all of this behind SSL.

First project with Adobe Illustrator CC

Written by Michael Earls
 featured  Illustrator

Laurie’s new job has her teaching preschool at the Jewish Educational Alliance here in Savannah. As part of her teaching, she needed a wheel that would let her students know what the day’s activity would be. I decided to create it for her using Adobe’s new Illustrator Creative Cloud.

Here is a PDF containing the final product: ActivityWheel

Activity Wheel

Most of the work I did involved finding Creative Commons images on the web and converting them to line drawings, then cleaning up the paths.

The activities are:

  • Monday – Sandbox
  • Tuesday – Painting
  • Wednesday – Skating
  • Thursday – Water table
  • Friday – Spray Painting (with paint in a spray bottle)

I really like the new Illustrator. I still haven’t decided if I can pay the $20/month for it, though. I have the Photoshop/Lightroom special of $9.99/month already.

Enabling Basic Authentication for Angular and jQuery clients for your ASP.NET WebApi

Written by Michael Earls
 ASP.NET  featured  security  WebAPI

I have been working on a WebAPI for a client over the past few months and I’ve successfully implemented Basic authentication on my WebAPI and connected to it using a Xamarin Android client.

I’ve come to a point where I need to start supporting AngularJS clients, but I don’t like how the browsers each have their own default login dialogs that are ugly. I found a great blog entry solving this exact issue, but the author wrote their server side in Sinatra.

Here is the blog entry with the situation and solution:

http://olefriis.blogspot.com/2014/01/http-basic-authentication-in-angularjs.html

You’ll need to implement Basic authentication on your WebAPI to make this work. To implement Basic authentication on your ASP.NET WebAPI, follow the instructions here:

http://www.asp.net/web-api/overview/security/basic-authentication

One thing to make sure you do (in Web.config) is change the

type="WebHostBasicAuth.Modules.BasicAuthHttpModule, BasicAuth"

to reflect the project name and binary name of your project (your’s shouldn’t be named WebHostBasicAuth.Modules.BasicAuthHttpModule. It will be the name of your project instead.

type="{ProjectName}.Modules.BasicAuthHttpModule, {BinaryName}

It turns out that the changes required to make the solution outlined in Ole Friis Østergaard’s post is very easy to implement in ASP.NET.

Here is the code you need to change in the Basic Authentication Implementation from above:

// If the request was unauthorized, add the WWW-Authenticate header  
// to the response. 
private static void OnApplicationEndRequest(object sender, EventArgs e)  
{
    var response = HttpContext.Current.Response; 
    // see if the request sent an X-Requested-With header (Non-Browser request - 
    // used by jQuery and Angular implementations to prevent the browser from 
    // presenting the default Login dialog) 
    var request = HttpContext.Current.Request; 
    string authType = "Basic"; 
    if (response.StatusCode == 401) 
    { 
        if (request.Headers.AllKeys.Contains("X-Requested-With")) 
        { 
            if (request.Headers["X-Requested-With"] == "XMLHttpRequest") 
            { 
                authType = "xBasic"; 
            } 
        } 
        response.Headers.Add("WWW-Authenticate", string.Format("{0} realm="{1}"", authType, Realm));
    } 
}

That’s it! Now, when you pass in the X-Requested-With header value of "XMLHttpRequest", you’ll get back a WWW-Authenticate header with a type of “xBasic” instead of “Basic”. That will cause the browser to ignore the request and suppress the login dialog, letting you display your own pretty dialog.

I have started a GitHub project that has my Sample WebAPI in it. I’ll be updating that to include the AngularJS code as I create it to demonstrate exactly how to pull this off since Ole’s post is light on details.

Here is the GitHub project:

https://github.com/cerkit/BasicAuthWebApiSample.git

What lies beyond the limits of Mathematics?

Written by Michael Earls
 featured  macrocosm  Mathematics  microcosm  Universe

I’ve been thinking about the universe lately and I’ve started wondering if the limitations of our understanding of the universe lies in the fact that our language of mathematics has limitations. Seriously, most of our observations (microcosms and macrocosms) are based on deep mathematics. At the end of that language of numbers and theorems lies something greater than our collective intelligence.

How can we describe our universe with mathematics alone? Even our calculations of the distances to stars and other celestial bodies is based on color shifting and radio waves which must be processed. I’m not saying that the nearest galaxy is only a few light days ahead, I’m just suggesting that our limit of understanding isn’t necessarily caused by stupidity. It’s merely a limitation of our understanding of the universe as it relates to the language of mathematics.

What if there was another language we could use? I’m not referring to religion, I’m suggesting that there might yet be an undiscovered language we can use to apply to the unknown universal truths. Something that doesn’t even require an “intelligent design versus evolution” war. Maybe I’m just referring to the “all inclusive theory of everything”. :)

What if this language could teach us that light isn’t the fastest known thing in the universe? What if it could reveal to us that time and light are connected in such a way that time would adjust to an increase in the speed of light so as to keep the balance there? Oh well, I’m spouting BS now.

Just something I’ve been pondering lately.

Note: Featured image taken from http://www.wallshq.com/nature/microcosm-wp-1920×1200-by-trystianity

First Gaming Systems

Written by Michael Earls
 atari  c64  coleco  commodore 64  featured  gamer  Gaming  nostalgia

When I was a kid, our first home gaming machine was the Telstar Pong console.

telstaralpha

I think it had four “games” and three levels of difficulty (the size of the “paddle” got smaller). Oddly enough, I still have this thing, though I cut the video cable off of it for some project I was working on as a kid.

After that, we got an Atari 2600. Man, this thing rocked our world. My brother and I would always play the included Tank game (“Combat”). I also had a good friend that had one and we would swap games. I think it’s also the first game to have a “cheat”. You could bump the tank against the corner and “warp” to the other side.

Atari 2600

Combat

And, of course, no conversation about the Atari 2600 can go without mentioning the awesome “Pitfall!”

Pitfall!

After that, my first “real” computer…the TI-99/4A

TI-99_4A

We had a cassette player that we stored the programs on. Oh man, this thing was cool. I remember a dungeon crawling adventure game that I’d play for hours. I don’t remember the name of it, but it was cool. This was also where I was first introduced to “Hunt the Wumpus”, a great puzzle game.

wumpus

Wumpus Gameplay

After that, my mom got us a Colecovision “Adam” home computer. It was a gaming console, but it also had a built in daisywheel printer and it booted up as a word processor. We had CP/M for it and we had a machine language compiler, but that was over my head at the time. This was when I would have rather have gotten an IBM PC. It was pretty annoying because it had a high-speed tape drive and the tapes would get wrapped up in the spindle. The tapes had screws in them (a little foresight on Coleco’s part?) so it was easy to pop them open and reel them back in. It was still annoying, though.

Adam home computer

Them the big daddy of them all…the Commodore 64. My parents didn’t buy this one for me, I had to save up the money to get it for myself. I bought it off a guy in school for about $25 (including the hard drive). He was getting “old” and didn’t want to play with kid toys anymore. Sweet.

Commodore 64
(notice the price)

That’s pretty much it for my childhood gaming machines.

As a side note, compare the wumpus adventure game to this…

Elder Scrolls: Oblivion

That’s what I play as an adult on my XBox 360. If I could go back in time and show that game to me as a kid, I’d probably flip out and never leave the house. Oh, wait, that’s what kids are doing today, isn’t it?

Update: Here's the latest graphics from my XBox One (2016):

Destiny on XBox One

We've come a long way.