WedTM Seriously interesting business.

30Oct/090

Ruby Awesomeness

Here's a prime example as to why ruby is so freakin' cool.


# Ruby knows what you
# mean, even if you
# want to do math on
# an entire Array
cities  = %w[ London
              Oslo
              Paris
              Amsterdam
              Berlin ]
visited = %w[Berlin Oslo]

puts "I still need " +
     "to visit the " +
     "following cities:",
     cities - visited
Filed under: Ruby No Comments
4Aug/090

I’m finally getting my money from that Nigerian guy!

I really don't understand what's going on here....

Attn:, I am Mrs Mary Susan Fredrick,

I am a US citizen, 48 years Old. I reside here in New Braunfels Texas. My residential address is as follows. 108 Crockett Court. Apt 303, New Braunfels Texas, United States. I am one of those that executed a Compesation in Nigeria, many years ago and they refused to pay me, I had paid over $20,000 while in the US, trying to get my payment all to no avail.

So I decided to travel down to Nigeria with all my compensation documents, And I was directed to meet Mr.Scott Gill, who is the member of COMPENSATION AWARD COMMITTEE, and I contacted him and he explained everything to me. He said whoever is contacting us through emails are fake.

He took me to the paying bank for the claim of my Compensation payment. Right now I am the most happiest woman on earth because I have received my compensation funds of $500,000.00 Moreover, Mr Scott Gill, showed me the full information of those that are yet receive their payments and I saw your name as one of the beneficiary, and your email address, that is why I decided to email you to stop dealing with those people,they are not with your fund, they are only making money out of you. I will advise you to contact Mr Scott Gill

You have to contact him direct on this information below.

MR SCOTT GILL COMPENSATION HOUSE
Name:Mr.Scott Gill.
Email: mr_scott_fedexdelivery01@yahoo.com.hk
Tel: +234-807-909-3316
Office Address: 13, Cole Street, Ikeja Lagos Nigeria.

You really have to stop dealing with those people that is contacting you and telling you that your fund is with them, it is not in anyway with them, they are only taking advantage of you and they will dry you up until you have nothing.The only money I paid was just $520,take note of that.

Once again stop contacting those people, I will advise you to contact Mr Scott Gill so that he can help you to Deliver your fund instead of dealing with those liars that will be turning you around asking for different kind of money to complete your transaction.

Thank You and Be Blessed.
Mrs. Laura Susan Fredrick.

4Aug/090

Automatic Disable/Enable of AD Account

I've recently come across a weird issue with in my AD domain structure where users's permissions seem to just "disappear". The users' account is still there, it's active, and they're account shows up in all the right places, however, when they attempt to access a resource, the resource doesn't verify them.

I haven't nailed down the issue yet, but I have found a fix. Simply disabling and then re-enabling the account fixes it for an indeterminate amount of time.

I've gotten tired of pulling up ADU&C so I've created a nice little app that I set in my System32 to automagically disable and then re-enable their account. Here's the source:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;

namespace FixUser
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length != 0)
            {
                SearchResultCollection coll = UserExists(args[0]);
                DirectoryEntry de = coll[0].GetDirectoryEntry();
                Disable(de);
                Enable(de);
                Console.Write("Done.");
                Console.Read();
            }
            else
            {
                Console.Write("Enter any part of the users name: ");
                string firstName = Console.ReadLine();
                SearchResultCollection coll = UserExists(firstName);
                Console.Write("Pick a user: ");
                string item = Console.ReadLine();
                DirectoryEntry de = coll[Convert.ToInt32(item)].GetDirectoryEntry();
                Disable(de);
                Enable(de);
                Console.WriteLine("The user should be able to login again.");
                Console.WriteLine("Press any key to exit...");
                Console.Read();
            }
        }

        public static SearchResultCollection UserExists(string username)
        {
            DirectoryEntry de = GetDirectoryEntry();
            DirectorySearcher deSearch = new DirectorySearcher();

            deSearch.SearchRoot = de;
            //deSearch.Filter = "(&(objectClass=user) (cn=" + username + "))";
            deSearch.Filter = "(&(objectCategory=user)(objectClass=person)(mail=*)(cn=*" + username + "*)(!userAccountControl:1.2.840.113556.1.4.803:=2))";
            SearchResultCollection results = deSearch.FindAll();
            int i = 0;
            foreach (SearchResult res in results)
            {
                DirectoryEntry person = res.GetDirectoryEntry();
                string cn = String.Empty;
                string sam = String.Empty;

                if (person.Properties["cn"].Value != null)
                    cn = person.Properties["cn"].Value.ToString();

                if (person.Properties["samAccountName"].Value != null)
                    sam = person.Properties["samAccountName"].Value.ToString();

                Console.WriteLine("[" + i.ToString() + "] " + cn + " (" + sam + ")");
                i++;
            }
            return results;
        }
        public static DirectoryEntry GetDirectoryEntry()
        {
            DirectoryEntry de = new DirectoryEntry();
            de.Path = "LDAP://DC=HEADQUARTERS,DC=LOCAL";
            de.AuthenticationType = AuthenticationTypes.Secure;
            return de;
        }

        public static void Enable(DirectoryEntry user)
        {
            try
            {
                int val = (int)user.Properties["userAccountControl"].Value;
                user.Properties["userAccountControl"].Value = val & ~0x2;
                //ADS_UF_NORMAL_ACCOUNT;
                user.CommitChanges();
                user.Close();
            }
            catch (System.DirectoryServices.DirectoryServicesCOMException E)
            {
                //DoSomethingWith --> E.Message.ToString();
            }
        }

        public static void Disable(DirectoryEntry user)
        {
            try
            {
                int val = (int)user.Properties["userAccountControl"].Value;
                user.Properties["userAccountControl"].Value = val | 0x2;
                //ADS_UF_ACCOUNTDISABLE;
                user.CommitChanges();
                user.Close();
            }
            catch (System.DirectoryServices.DirectoryServicesCOMException E)
            {
                //DoSomethingWith --> E.Message.ToString();
            }
        }
    }
}

the Disable and Enable methods were slightly modified from the original versions found here: http://www.codeproject.com/KB/system/everythingInAD.aspx#34

Filed under: C#, Tutorials No Comments
31Jul/090

Visual Studio 2008 on 7

I’ve recently upgraded my development machine to Windows 7 and found a tricky little issue that creeps up.

Now when I installed VS2008 on the system, I installed it with elevated permissions, and everything appeared to install correctly.

I could compile the project, however, whenever I’d try to debug the project, I would get an bland message stating:

Error while trying to run project: Unable to start debugging.

I tried forever and a day to figure out what was causing the issue, I repaired the remote debugger with the tools on my Visual Studio DVD, no luck. I even completely deleted the project and restarted, again, no luck.

Finally I came back to the good old days of Vista RTM and realized something.

UAC is a pain in the ass.

Even though I’d been running Visual Studio as Administrator, not all the processes that it spawned (namely the debugger) were getting the same elevated permissions.

Once I turned off UAC completely, debugging started working again, just like it should.

Lessons learned? Remember this for Windows 8, because apparently Microsoft hasn’t learned their lesson yet.

Filed under: Windows 7 No Comments
31Jul/090

Graphic Designer Needed!

I need a graphic designer to do some work on a very hush-hush project. There will be monetary compensation, depending on quality of work.

The extent of the project at this time would simply be a logo, with possible UI design further down the road.

If your interested, please leave a link to your portfolio in the comments.

Filed under: Jobs No Comments
30Jul/090

Wave Server

I’ve started development on my custom wave server. The first iteration is going to be C# and therefore only Windows based. I don’t plan to test it with Mono, but if someone gets the urge to, then let me know!

The first draft is going to be simply the client/server side. The next iteration will be cross-server coordination with Wave Protocol compatibility.

The main issue is that Google hasn’t specified any client – server communication protocol as of yet. Nor do they appear to even want to. So, because of this, I’m going to work on the client – server first, then I will try and connect it with their federated server example. Which, by then, should be mature enough that it’s not going to change ever two weeks.

 

I’ll keep you guys posted.

Filed under: Google Wave No Comments
30Jul/090

Windows 7 Window Shake

I just found out that if you shake a window by holding it’s title bar and moving your mouse up and down or left and right, the windows below it will minimize.

Do this again to have them reappear.

Seems like Microsoft likes easter eggs as much as the next guy!

Filed under: Windows 7 No Comments
27Jul/090

A look inside Nisme: Part 2

When I first started develolping Nisme, there was no clearly defined goal. Really my whole idea was to simply learn how the site functioned and to learn the proper use of JSON in the mean time.

It took me down a very slippery slope.

In this post, I'm going to talk about a small chunk of how I actually came across the raw MP3 stream that Lala sends to it's flash player. I started with the simple idea (that I stand behind today):

If I can do it in a browser, I can do it progmatically.

This took me to follow the request through lala's many layers of Javascript, and backend calls. I first found that there seemed to be something missing. It seemed that there was one call to:

playUrl

that didn't really go anywhere. It just executed. So I took my time, and after all options were exahusted, I looked in the unlikeliest of places. I figured that the flash player was simply a dummy control for the javascript behind it. I was wrong.

Inside the .swf was the actual player. They were hashing a JSON value called playToken along with an extremely long and foreboding "don't copy this stream or we'll cut off your neck and spit down your throat" copyright warning. Once I found that, I started passing it along to another URL that sent back a play URL. THe problem with these play URL's was that they were only good for one play. That's right, the second time you requested them you got a nice little 404 error.

Secondly, and this wasn't added until later, they check for the presence of your login cookie as well. This small fact has been the cause of many headaches in the Nisme development tree. It's extremely simple to play an MP3 url from a remote source on lots of platforms, however, sending a header value first proved difficult to say the least.

As far as source code goes, here is the actual retrieval of the playLink:


public String PlayLink
{
    get
        {
            string hash = this.PlayToken + "Warning: Unauthorized reproduction, capture or distribution of this stream can result in civil and criminal liability. This stream and its content is owned by la la media, inc. and/or its licensors, and is protected by applicable intellectual property and other laws, including but not limited to copyright.   To prevent unauthorized and infringing uses of this stream, generation of an MD5 digest with this text is required and will be used for monitoring and tracking unauthorized and infringing activity." + "abs123";
            System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] data = System.Text.Encoding.ASCII.GetBytes(hash);
            data = x.ComputeHash(data);
            string ret = "";
            for (int i = 0; i < data.Length; i++)
            ret += data[i].ToString("x2").ToLower();
            string md5t = ret;
            string T = this.PlayToken;
            T = T.Replace("-", "%2D").Replace("=", "%3D").Replace("+", "%2B").Replace("/", "%2F");
            string TS = this.Timestamp;
            string URL = "http://www.lala.com/api/Player/getPlaybackUrl?T=" + T + "&webSrc=lala&md5T=" + md5t + "&flash=true&TS=" + TS + "&debugPagePath=bigdPlayer&xml=true";
            string xml = API.HTTPRequests.GetData(URL);
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(xml);
            XmlNodeList result = xdoc.GetElementsByTagName("url");
            return result[0].InnerText;
        }
    }

Of course all of this is online at the repo locate at http://nisme.googlecode.com/

Filed under: Nisme, Tutorials No Comments
27Jul/092

MS or OS?

I've been fighting an internal battle recently as to whether or not I should focus on OS (RoR, PHP, Java, Python) or go the MS route (.NET, WCF, WPF, C#). I enjoy the simplicity of Visual Studio so much, that recently I've focused quite a bit of my resources on WPF, however, I feel dirty in doing so.

I really feel like I should be giving back to the community that has given me so much, and yet, I can't seem to make the leap. I am trying to take full advantage of all the issues that plague me day to day by adapting to the most reasonable format, however, I seem to be stuck in this endless loop of trying to please this insatiable thirst for "more".

Grrr....

Filed under: Uncategorized 2 Comments
15Jul/090

A Look Inside Nisme: Part 1

For those of you who don't know, Nisme is being developed with out any offical support from Lala. They don't have an official API, and the ones that I'm using are the exact same ones their site uses to provide the service.

This does pose a very large problem. What happens if Lala changes up their API? Well that has come up in my development brainstorming sessions, however, I think I've come up with quite a few "good-enough" ideas.

This leads me to my next topic. I am going to start a small mini-series on key components of Nisme. That way, you can see how I've interacted with Lala's data, and also give pointers if you see any glaring issues! So, for Part 1, I'm going to show you how I keep the authentication with lala through out the session.

 


public static bool GetLoginCookie(string username, string password)
{
    string URL = "https://www.lala.com/api/User/signin/" + API.Functions.CurrentLalaVersion() + "?email=" + username + "&amp;userpwd=" + password + "&amp;xml=true";
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
    request.CookieContainer = new CookieContainer();
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    string plate = "uiFc=homeNoAuthBSignin; ";
    foreach (Cookie cook in response.Cookies)
    {
        plate = plate + cook.ToString() + "; ";
    }
    Stream dataStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(dataStream);
     string responseFromServer = reader.ReadToEnd();
    reader.Close();
    dataStream.Close();
    response.Close();
    XmlDocument xDoc = new XmlDocument();
   xDoc.LoadXml(responseFromServer);
   XmlNodeList id = xDoc.GetElementsByTagName("userToken");
   XmlNodeList err = xDoc.GetElementsByTagName("errorCode");
   string UserID = id[0].InnerText;
   string ErrorCode = err[0].InnerText;
   if (ErrorCode != String.Empty)
   {
        return false;
   }
   else
   {
        API.Constants.Cookie = plate;
        API.Constants.UserID = UserID;
        return true;
    }

}

Let's pull this apart for a second.

 


string URL = "https://www.lala.com/api/User/signin/" + API.Functions.CurrentLalaVersion() + "?email=" + username + "&amp;userpwd=" + password + "&amp;xml=true";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.CookieContainer = new CookieContainer();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

These lines are pretty simple. They setup a RESTful API call to lala's User.signIn module. It's important to note that Lala by default will return JSON formatted values. While talking with a developer at Lala, I was informed that by appending <pre>&xml=true</pre> to the end of the query string, I can
get an xml formated value back.

I've flopped between JSON and XML through out Nisme's lifecycle, and the code shows it. In some of my methods, I use extremely hacked together raw string parsing to get my values, later on, I switched to XML, and with the WPF version, I'm back to JSON. More than likely I'll be sticking with JSON, simply because I've found a library that I'm comfortable working with, and JSON is just more lightweight in my opinion.


string plate = "uiFc=homeNoAuthBSignin; ";
foreach (Cookie cook in response.Cookies)
{
    plate = plate + cook.ToString() + "; ";
}

 For some reason, and don't ask me why, the <pre>plate</pre> has to be appended manually. I couldn't find in what part of the stack lala set this cookie, but it was always set to <pre>homeNoAuthBSignin</pre> so I figured it wouldn't hurt to manually force it. The next couple of lines are pretty self explanitory, as they simply loop through all the retrieved cookies and append them to <pre>plate</pre>.


Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();

 Here we are retrieving the actual data of the response. Up until now, we've only been parsing header values. We'll do a bit of garbage collection by closing all the uneeded resources as well.


XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(responseFromServer);
XmlNodeList id = xDoc.GetElementsByTagName("userToken");
XmlNodeList err = xDoc.GetElementsByTagName("errorCode");
string UserID = id[0].InnerText;
string ErrorCode = err[0].InnerText;

Again, pretty simple. We create a new <pre>XmlDocument</pre> and parse out the <pre>userToken</pre> and <pre>errorCode</pre> fields. The <pre>userToken</pre> field is only used currently for the naming of the Nisme Library File (.NLF). The <pre>errorCode</pre> is only used to detect if we had a successful login.

I guess in hind sight, it doesn't make sense to parse the headers if the login wasn't successful, now does it? (This will get changed in a later version)


if (ErrorCode != String.Empty)
{
    return false;
}
else
{
    API.Constants.Cookie = plate;
    API.Constants.UserID = UserID;
    return true;
}

Here's the actual logic check, and the assignment to the API.Constants singletons', plate and UserID.

 

So that's it! Each call that is made to lala after this, has the API.Constants.Cookie sent within it's header, and the rest is the magic of HTTP!

Filed under: Nisme, Tutorials No Comments