Development and energy

I recently read the book “Olja” (ISBN 91-7232-043-5) by Gunnar Lindstedt. Unfortunately it is only available in Swedish.

The book is about what is known as Peak Oil, i.e. the point in time when we have extracted 50% of the world’s oil supply. According to the experts interviewed in the book that point is here or very near. Actually, the date varies from “just passed it” to “within 10 years”. I’d say that is rather irrelevant. I firmly believe that the amount of oil is finite (if for nothing else the volume of the planet is finite) and it seems reasonable to believe the experts that the half-way point is near. Thus the time for action is close.

In the book mr Lindstedt not only explains details about oil extraction ond consumption, he also parallells this with backdrops from a “middle earth” era. His youth and his grand parents youth. So much has changed in the last 100 years it’s almost unbelievable, and not only in terms og technology.

Mr Lindstedt suggests that the curve of the western world’s improved efficiency in production is virtually identical to the curve of oil import. That idea took me by surprise, and after pondering it it does make sense.

Way back when a man and his horse would till a field in a day or two (or whatever). Now, a man and his tractor does it significantly faster, and things look more efficient on the surface. However, that doesn’t take into account the hidden addition of a few hundred litres of diesel.

So, thinking about it, have we made significant improvements in terms of process, or are all our increases in efficientcy by shortening the time and adding energy? Somewhere in the back of my mind a page from a physics book lurks, mumbling something about efficiency as work x time. As long as we only count human power as “work” and forget about the work fossil fuel does we look a lot more efficient, but that seems like a small white lie…

Scanning the net I found a link to http://www.eia.doe.gov/ipm/supply.html with the oil production of various countries  and summaries.

oilproduction

It seems the world is indeed reducing its production and it s worth noting that the current economic slump/crisis/depression is not in these numbers, as they only include up to 2007.

Interesting read and lots of food for thought. For further reading, google for peak oil.

–Jesper Hogstrom

  • Share/Bookmark

Subtitles to your movies

There are several times you may want to add subtitles to movies. The question is how to find them. I usually use google but there are plenty of sites that offer the goods (the subtitles, not the movies!)

Have fun!

–Jesper Hogstrom

I

  • Share/Bookmark

Gain ssh access to ReadyNAS

In my server closet I run a Netgear ReadyNAS+ with 1.5TB of effective storage. It’s a really neat box with support for various access methods, like nfs, ftp, http and cifs and a few more.

My latest informational reorg included an idea to publish sound and video on a share that the kids could access. All that stuff used to sit on a share deep in a structure from a previous box I used to run.

Easy thing to figure out what to do; simply create a new share, call it Media and allow all the internal network read-access.  Mount it on a linux box with root access, then move everything from the old jesper/backup/jesper/bigdrive/private/media to that directory.

The only thing is that it’s not possible to simply rewrite the inodes when moving things from one nfs-mounted volume to another nfs-mounted volume. Every single bit needs to be copied.

It was a somewhat lengthy procedure to move everything onto the NAS, but at that time I had a gigabit card (still have it but it is not recognized by vmware esxi) and data was only going one way – from one box onto the NAS. This time, I was stuck with a 100MBit nic and data had to travel from the NAS, to the computer and then back to the NAS. Admittedly I didn’t have to watch, but I figured it would take me days to shuffle all of that data.

As the ReadyNAS runs a linux distro behind the scenes I figured the solution would be to gain terminal access to the NAS using ssh. Unfortunately that wasn’t on by default. I googled and found several solutions to fix the problem, ranging from opening the NAS and mounting the disks on another computer to using some odd “feature” in Apple File Protocol and hacking the crontab file.

Eventually I found a much simpler solution: Installing the official ‘enable ssh access’ patches. :)

On http://www.readynas.com/?page_id=94 you’ll find – at the bottom of the page – two patches; ToggleSSH and EnableRootSSH. Both need to be installed, and the NAS wants to reboot after each one.

ssh into the nas. Log in as root with your existing admin password. Voila! you’re in!

Now moving the remaining data was a few keystrokes away and obviously lightning fast using the good ol’ mv command.

Happy hacking!

–Jesper Hogstrom

  • Share/Bookmark

See you in Motala

Better late than never. We finally got around to register to VätternRundan. It’s a 300 kilometer bicycle trip around lake Vättern in the middle of Sweden. This year me and Jonas will do our third trip and we somehow managed to trick our brother Christer into joining us.

It’s going to be great fun. We start around one am which isn’t my favorite time – I prefer starting earlier, as it is impossible for me to nap during the evening.

Last year we started about that time too, and we had all intentions of napping. We parked the car in central Motala near a lawn. Had dinner, looked at the commotion at the city square and all the cool bicycle gear up for sale. Went back to the car, unpacked our sleeping bags and lay down on the lawn, set the alarm and hoped to get some sleep.

After 5 minutes the first drops came down. I tried to pretend it didn’t rain. Another 10 minutes of increasing precipitation  and I said to Jonas that we’ll stay the course – it will end soon. Yeah, right… We spent the next two hours in the car while the rain poured down…

Luckily it cleared up and the weather during the ride was excellent.

Anyway, time to get mentally ready for those 100km training trips – and of course gather some nice stuff to listen to. Last year I found a 10 hour series about the Greek-Persion wars which was very interesting. Given the fact that I have forgotten most of it I might as well listen to it again :)

See you in Motala!

–Jesper Hogstrom

  • Share/Bookmark

Nested foreach in ECO report generator

As Jonas pointed out in a comment to my last post, it was not possible to nest foreach-loops in the report.

One minor change was required to support that, namely the locating of the position of the – matching – {/foreach}.

Original code looked like:

  1. if (toExpand.StartsWith(startForeach))
  2. {
  3.   endPos = s.IndexOf(endForeach, endPos);   // <– This line finds the next {/foreach} – not the matching one
  4.   string repeatBlock = s.Substring(i + toExpand.Length + 2, endPos – i – toExpand.Length2);
  5.   expanded.Append(ExpandBlock(roots, toExpand, repeatBlock));
  6.   i += toExpand.Length + repeatBlock.Length + endForeach.Length + 1;
  7.   break;
  8. }

Instead, that has to change to

  1. if (toExpand.StartsWith(startForeach))
  2. {
  3.   endPos = GetMatchingEndPos(s, endPos);
  4.   if (endPos == -1)
  5.   throw new InvalidOperationException(string.Format("Unable to find matching /foreach after start on pos {0}", i));
  6.   string repeatBlock = s.Substring(i + toExpand.Length + 2, endPos – i – toExpand.Length2);
  7.   expanded.Append(ExpandBlock(roots, toExpand, repeatBlock));
  8.   i += toExpand.Length + repeatBlock.Length + endForeach.Length + 1;
  9.   break;
  10. }

Again, interesting lines of code somewhere else (the method was already way too long for my taste anyway!}

  1. private int GetMatchingEndPos(string s, int startPos)
  2. {
  3.   int result;
  4.   int openCount = 1;
  5.   do
  6.   {
  7.     result = s.IndexOf(endForeach, startPos);
  8.     int nextOpen = s.IndexOf(startForeach, startPos);
  9.  
  10.     if (nextOpen == -1 || nextOpen > result)
  11.     {
  12.       openCount–;
  13.       startPos = result + 1;
  14.     }
  15.     else
  16.     {
  17.       openCount++;
  18.       startPos = nextOpen + 1;
  19.     }
  20.   } while (openCount > 0);
  21.   return result;
  22. }

What the code does is look for the next open and close token. If the first token is “open”, increase the openCount. If the next token is “close”, decrease openCount. Next time, start looking after the first token found. If the openCount is zero, we’ve found ourselves a match.

This can be tested with template strings like

{foreach:Person.allInstances}
  outer {Person:self.fullName}
  {foreach:Person.allInstances}
  inner {Person:self.fullName}
  {/foreach}
  {foreach:Person.allInstances}
  inner2 {Person:self.fullName}
  {/foreach}
{/foreach}

i.e. a sequence of “start start stop start stop stop”. The sequences I alread had works fine still, as well as “start start stop stop”. Should be pretty safe.

–Jesper Hogstrom

  • Share/Bookmark

Simple report generator for ECO

Ever so often customers want things printed. It may be a recepit, a complex report, an inventory list or just a page about the customer object being viewed.

Thus I found myself volonteering to write a library system (simple book lending and returning) for a friend. I had implemented the most critical parts of the system (lending and returning) when I realized the current system they have print a lending receipt and a return receipt. So, rather than learning everything there is to know about printing and pixel adjustments of labels I decided to cheat just a little bit.

My first realization was that if I could generate a html-file with the required information, I could rely on a browser to render and print the receipts. That simple thought reduced the problem to how to generate the html-file.

My second idea was that instead of generating the full html-file, I would be better off expanding a html template. That way the system is future proof in the sense that a change in the layout of the printed stuff does not require programming, merely updating the template.

Now the problem is reduced to data driven template expansion.

Using ECO this should be a no-brainer, given the ability to use OCL to query the object layer without having to worry about fetching information from a storage backend.

I set out to write a general purpose expansion service with an interface initially looking like the following.

  1. public interface IExpansionService
  2. {
  3.   string Expand(IElement[] roots, string s);
  4. }

Simplistic, yes, but it can easily be expanded to cover a few more bases.

Then I pondered an expansion language. As can be guess from the interface, I would like to be able to pass several objects that can serve as root elements when evaluating OCL.

I finally settled for the following:

Hello {Person:self.firstName}!

You have purchased the following items:

{foreach:Invoice:self.invoiceItems}

* {Product:self.quantity} pieces of {InvoiceItem:self..Product.Name}

{/foreach}

(Add html elements as you please)

The things I need to parse are expressions within curly brackets. What is inside curly brackets are either:

* typename colon expression – must yield a string* “foreach” colon typename colon expression – must yield a collection

* “/foreach”

First, add a method to implement the interface.

  1. public string Expand(IElement[] roots, string s)
  2. {
  3.   return ExpansionCore(roots, s).ToString();
  4. }

It’s pretty clear  that I’ve hidden all the goodies in ExpansionCore.

  1. private StringBuilder ExpansionCore(IElement[] roots, string s)
  2. {
  3.   string startForeach = "foreach:";
  4.   string endForeach = "{/foreach}";
  5.  
  6.   StringBuilder expanded = new StringBuilder();
  7.   for (int i = 0; i < s.Length; i++)
  8.   {
  9.     char c = s[i];
  10.     switch (c)
  11.     {
  12.       case \\:
  13.         expanded.Append(s[++i]);
  14.         break;  
  15.  
  16.       case ‘{’:
  17.         int endPos = s.IndexOf(‘}’, i);
  18.         string toExpand = s.Substring(i + 1, endPos – i – 1);
  19.         if (toExpand.StartsWith(startForeach))
  20.         {
  21.           endPos = s.IndexOf(endForeach, endPos);
  22.           string repeatBlock = s.Substring(i + toExpand.Length + 2, endPos – i – toExpand.Length2);
  23.           expanded.Append(ExpandBlock(roots, toExpand, repeatBlock));
  24.           i += toExpand.Length + repeatBlock.Length + endForeach.Length + 1;
  25.           break;
  26.         }
  27.         i += toExpand.Length + 1;
  28.         expanded.Append(ExpandString(roots, toExpand));
  29.         break;
  30.  
  31.       default:
  32.         expanded.Append(c);
  33.         break;
  34.     }
  35.   }
  36.   return expanded;
  37. }

The special handling of back-slash allows the escaping of curly brackets. It also means back-slashes must be escaped.

If the upcoming character is an opening bracket, then simply find the closing bracket. If the string in between starts with “foreach” we handle it in ExpandBlock. Otherwise the string is expanded using ExpandString.

ExpandString doesn’t need to do much, really.

  1. private string ExpandString(IElement[] roots, string toExpand)
  2. {
  3.   return EvaluateExpression(roots, toExpand).GetValue<string>();
  4. }

Again, interesting bits are elsewhere. Let’s take a peek at EvaluateExpression.

  1. private IElement EvaluateExpression(IElement[] roots, string toExpand)
  2. {
  3.   var ocl = ServiceProvider.GetEcoService<IOclService>();
  4.   string[] parts = toExpand.Split(new char[] { ‘:’ }, 2);
  5.   string expression = toExpand.Trim();
  6.   IElement root = null;
  7.   if (parts.Length == 2)
  8.   {
  9.     root = GetRootElement(parts[0].Trim(), roots);
  10.     expression = parts[1].Trim();
  11.   }
  12.   return ocl.Evaluate(root, expression);
  13. }

Here we see that the string toExpand is split at the colon. If the resulting array is of length 1, then we didn’t specify a root type, and we simply use no root. That is perfectly ok for expressions like “Color.allinstances->first.colorname”.

Thanks to the OclService in ECO there is no need to worry about how to actually evaluate the string. Just get the service and invoke Evaluate. Before I forget, I passed an IEcoServiceProvider to the constructor of my ExpansionService.

There is one interesting bit left in EvaluateExpression – GetRootElement.

What I wanted was to specify the type by modeled name, and then match that against the  modeled names of the elements in the submitted IElement[] roots.

  1. private IElement GetRootElement(string typename, IElement[] roots)
  2. {
  3.   string[] nameparts = typename.Split(new char[] { ‘[', ']‘ });
  4.   int rootIndex = 0;
  5.   if (nameparts.Length > 1)
  6.   {
  7.     typename = nameparts[0].Trim();
  8.     rootIndex = int.Parse(nameparts[1].Trim());
  9.   }
  10.   int scanCount = 0;
  11.   foreach (var element in roots)
  12.   {
  13.     if (element.UmlType.Name.Equals(typename, StringComparison.InvariantCultureIgnoreCase) &amp;&amp; (scanCount++ == rootIndex))
  14.     return element;
  15.   }
  16.   return null;
  17. }

Again, I have deviated from the grammar specification. As you may or may not realize the type name can be followed by an index in hard brackets. If the index is left out, the first match is used. The rationale for this is that I might want to pass in two root elements of the same type, so there must be a way to select the first or the second of them.

The only part left to investigate is the ExpandBlock method.

  1. private string ExpandBlock(IElement[] roots, string toExpand, string repeatBlock)
  2. {
  3.   StringBuilder result = new StringBuilder();
  4.   IElementCollection list = EvaluateExpression(roots, toExpand.Substring(toExpand.IndexOf(‘:’) + 1)).GetAsCollection();
  5.   foreach (IElement element in list)
  6.   {
  7.     List<IElement> newRoots = new List<IElement>(roots);
  8.     newRoots.Insert(0, element);
  9.     result.Append(Expand(newRoots.ToArray(), repeatBlock));
  10.   }
  11.   return result.ToString();
  12. }

Given the neat partitioning of the code above, there’s not much required to expand the block.

First, evaluate the expression into an IElementCollection.

Then iterate over the collection and build a new IElement-array with the current element added as the first root element.

Finally use the new root array and expand the block using the Expand method.

Test it by something like:

  1. Person p1 = new Person(EcoSpace);
  2. p1.firstName = "Wolfgang";
  3. Person p2 = new Person(EcoSpace);
  4. p2.firstName = "Amadeus";
  5. MessageBox.Show(EcoSpace.ExpansionService.Expand(new IElement[] { p1.AsIObject(), p2.AsIObject() }, "First we have {Person:firstName} and then of course  {Person[1]:firstName}"));

Such nifty code requires the service to be registered and exposed as a property:

  1. public EcoProject1EcoSpace(): base()
  2. {
  3.   InitializeComponent();
  4.   this.RegisterEcoService(typeof(IExpansionService), new ExpansionService(this));
  5. }
  6. public IExpansionService ExpansionService { get { return GetEcoService<IExpansionService>(); } }

It is pefrectly possible to reach this service from anywhere in your application where an IEcoServiceProvider is available. Notably inside your business methods.

I rapidly enhanced my interface slightly to look like

  1. public interface IExpansionService
  2. {
  3.   string Expand(IElement[] roots, string s);
  4.   string Expand(IObjectProvider[] roots, string s);
  5.   string ExpandFile(IElement[] roots, string fileName);
  6.   void ExpandTemplateIntoFile(IElement[] roots, string templateName, string targetName);
  7. }

Most of the additional functionality os trivial to implement. The overload that takes an array of IObjectProvider allows calls to shorten ever so slightly:

  1. MessageBox.Show(EcoSpace.ExpansionService.Expand(new IObjectProvider[] { p1, p2 }, "First we have {Person:firstName} and then of course  {Person[1]:firstName}"));

In the name of reuse, I chose the following implementation for the second Expand.

  1. public string Expand(IObjectProvider[] roots, string s)
  2. {
  3.   return Expand(IElementArray(roots), s);
  4. }
  5.  
  6. private IElement[] IElementArray(IObjectProvider[] roots)
  7. {
  8.   List<IElement> result = new List<IElement>();
  9.   foreach (var item in roots)
  10.   {
  11.     result.Add(item.AsIObject());
  12.   }
  13.   return result.ToArray();
  14. }

..figuring I probably want to overload the other interface methods too at some point in the future.

Here’s how my Print method looks on one of my business objects.

  1. public void Print()
  2. {
  3.   string fileName = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + Path.DirectorySeparatorChar +  "temp.html";
  4.   if (File.Exists(fileName)) File.Delete(fileName);
  5.   AsIObject().ServiceProvider.GetEcoService<IExpansionService>().ExpandTemplateIntoFile(new IElement[] { this.AsIObject() }, "receipt.html", fileName);
  6.   ProcessStartInfo pstart = new ProcessStartInfo("RUNDLL32.EXE");
  7.   pstart.Arguments = string.Format("MSHTML.DLL,PrintHTML \"{0}\"", fileName);
  8.   Process.Start(pstart);
  9. }

I got the details on how to print rendered html-files from http://www.robvanderwoude.com/printfiles.html#PrintHTM.

The above should give you enough to handle most of the every-day style printing efforts that your users want to do. There are no doubt countless ways code can be improved and made more generic, and I hope to hear from you how you have enhanced the basic idea.

Update: To support nested foreach-blocks, please refer to this post.

–Jesper Hogstrom

  • Share/Bookmark

Reusing icons in a winforms app using eco service mechanism

Windows.Forms may not be the hottest technology these days, but it’s a convenient platform to write to.

I’m currently writing an app for a friend using good ol’  windows forms. There’s one “main form” and then several forms for data entry, searching, data maintenance and so on. All, or at least most, of these forms have the same icon. For one thing – what if the icon I selected isn’t what my customer expected? Another thing is the resources used to store multiple copies of the icon. Not a whole lot, but still.

What I would want to do is set the icon on the main form and have all the other forms pick it up.  Now, there is no concept of main form, though one could probably make a reasonable guess from Application.OpenForms. However, I deceided not to investigate that avenue further, and instead define a service like

  1.  
  2. public interface IIconService
  3. {
  4.   void RegisterIcon(Form f);
  5.   void SetIcon(Form f);
  6. }

I implemented that in a very simple way as

  1.  
  2. public class IconService : IIconService
  3. {
  4.   private Icon icon;
  5.   public void RegisterIcon(Form f)
  6.   {
  7.     icon = f.Icon;
  8.   }
  9.  
  10.   public void SetIcon(Form f)
  11.   {
  12.     f.Icon = icon;
  13.   }
  14. }

Using the service mechanisms available in Enterprise Core Objects (ECO) it’s possible to install the service

  1.  
  2. public EcoProject1EcoSpace(): base()
  3. {
  4.   InitializeComponent();
  5.   this.RegisterEcoService(typeof(IIconService), new IconService());
  6. }

and make ita property of the ecospace

  1.  
  2. public IIconService IconService { get { return GetEcoService<IIconService>(); } }

In the constructor of the main form, register the main form’s icon.

  1.  
  2. public MainForm(EcoProject1.EcoProject1EcoSpace ecoSpace)
  3. {
  4.   InitializeComponent();
  5.   rhRoot.EcoSpace = ecoSpace;  
  6.   ecoSpace.IconService.RegisterIcon(this);
  7. }

In the constructor of the other forms, set the icon.

  1.  
  2. private frmSearchPersons(EcoProject1.EcoProject1EcoSpace ecoSpace)
  3. {
  4.   InitializeComponent();
  5.   rhRoot.EcoSpace = ecoSpace;
  6.   ecoSpace.IconService.SetIcon(this);
  7. }

Now, when changing the icon of the main form, it will ripple through to all the other forms, and we’ve shaved off a kB for each form in the application using the same icon.

–Jesper Hogstrom

  • Share/Bookmark

What’s with Enterprise Core Objects?

My last post was about writing code for Enterprise Core Objects, ECO.

As I intend to write more about ECO, I might as well give you the full story.

Way back when, in 1997, thanks to a series of improbable events I teamed up with Jan Norden, chief architect of Boldsoft and Henrik Jondell, CEO of Boldsoft to write a product called Bold for Delphi. During the next years we expanded the team to include amongst others Jonas Hogstrom (my brother) and we had great fun writing code and doing consultancy work for clients like the Swedish Government, the National Television Broardcast Corporation (SvT), the Swedish Armed Forces and others.

In 2002 we were hired as a team by Borland. We converted Bold for Delphi, a win32 product, to what would eventually become Enterprise Core Objects, a .Net product.

Late 2006 Borland decided to simplify their organization (or something – I was not privy to the discussions in the fancy corner of the C-level corridor) and terminated the Swedish development center, i.e. the ECO team was set free.

The team decided to continue work on the ECO code base and formed Capable Objects AB. Obviously this was done in friendly negotiations with Borland – simply stealing the code base was not an option :)

As time passed I decided to set my mind to something different and let the others continue the development of what is arguably the best model driven development platform on the planet.

However, despite having a day-time job in a slightly different area of the computer industry I still very much enjoy the concepts and programming model of ECO. Thus, I write the odd application or cobble together some proof of concept code in ECO. It’s those efforts that I have and will blog about.

My current relation to CapableObjects is such that I have no involvement in the daily operations or code cutting, but I do help out with (and host some of) their computer infrastructure and love to give feedback on the product and meet the guys for a beer or two. I still enjoy the benefit of having an email address on the capableobjects.com domain.

With that I consider the full disclosure as presented.

–Jesper Högström

  • Share/Bookmark

ECO and custom services

As you are well aware, ECO is heavily modularized by use of services.

You have surely noticed that when getting an eco service with code similar to

  1. var ocl = ServiceProvider.GetEcoService<IOclService>();

As things have matured, the DefaultEcoSpace now implements simple properties for the more common built-in services;

  1. // Summary:
  2. //     The IVariableFactoryService of the EcoSpace
  3. //
  4. // Remarks:
  5. //     The IVariableFactoryService contains methods for creating free standing ECO
  6. //     elements that can be used as variables. The elements returned will implement
  7. //     IElement, and any other applicable interfaces from the Eco.ObjectRepresentation
  8. //     namespace.  This propery is equivalent to retieving the IVariableFactoryService
  9. //     from an IEcoServiceProvider using GetEcoService(typeof(IVariableFactoryService)).
  10. public IVariableFactoryService VariableFactory { get; }
  11. //
  12. // Summary:
  13. //     The IVersionService of the EcoSpace
  14. //
  15. // Remarks:
  16. //     The IVersionService is used for accessing historical values of ECO objects.
  17. //      This propery is equivalent to retieving the IVersionService from an IEcoServiceProvider
  18. //     using GetEcoService(typeof(IVersionService)).
  19. public IVersionService Versioning { get; }

and quite a few more.

What is not obvious at first glance is that anyone can register a service by means of the method DefaultEcoSpace.RegisterEcoService(Type type, object instance). As with any other service, the services you register are available from any service provider in which they are registered.

Here’s an idea I probably got from Peter Morris; add your own ICurrentUserService.

The idea is to have a globally available service that can tell you who – if anyone – is logged in.

My suggestion for an interface looks like:

  1. public interface IUserService<T>
  2. {
  3.   bool Login(string userName, string password);
  4.   void Logout();
  5.   T CurrentUser { get; }
  6.   bool IsLoggedIn { get; }
  7. }

The reason for a generic interface is to avoid linking it to the specific model.

The implementation is fairly straight forward. Note that there is a hard coded OCL expression that may or may not be suitable for you. It’s easy to change that to be set by a parameter. One of those famous exercises for the reader.

  1. public class CurrentUserService<T>: IUserService<T>
  2. {
  3.  private IEcoServiceProvider ServiceProvider { get; set; }
  4.  public CurrentUserService (IEcoServiceProvider serviceProvider)
  5.  {
  6.    ServiceProvider = serviceProvider;
  7.  }
  8.  public bool Login(string userName, string password)
  9.  {
  10.    var variables = ServiceProvider.GetEcoService<IVariableFactoryService>().CreateVariableList("var_username",  userName);
  11.    variables.AddConstant("var_password", password);
  12.  
  13.    var ocl = ServiceProvider.GetEcoService<IOclService>();
  14.    IList<T> users = ocl.Evaluate("User.AllInstances->select((username = var_username) and (password = var_password))->First", variables).GetAsIList<T>();
  15.    if (users.Count == 1)
  16.    {
  17.      currentUser = users[0];
  18.      return true;
  19.    }
  20.    return false;
  21.  }
  22.  
  23.  public void Logout()
  24.  {
  25.    currentUser = default(T);
  26.  }
  27.  private T currentUser;
  28.  public T CurrentUser
  29.  {
  30.    get
  31.    {
  32.       if (IsLoggedIn)
  33.          return currentUser;
  34.       return default(T);
  35.    }
  36.  }
  37.  public bool IsLoggedIn
  38.  {
  39.    get { return ServiceProvider != null &amp;&amp; currentUser != null; }
  40.  }
  41. }

Add this to the pool of services in the constructor of your ecospace

  1. public EcoProject1EcoSpace(): base()
  2. {
  3.   InitializeComponent();
  4.   this.RegisterEcoService(typeof(IUserService<User>), new CurrentUserService<User>(this));
  5. }

Make it a first class citizen by adding a property for it

  1.  public IUserService UserService { get { return GetEcoService<IUserService<User>>(); } }

After that, you can login, check for current user and what you may need.

Here’s the OK event on my login form

  1. private void btnOk_Click(object sender, EventArgs e)
  2. {
  3.   var userService = EcoSpace.GetEcoService<IUserService<User>>();
  4.   if (!userService.Login(tbxUsername.Text, tbxPassword.Text))
  5.   {
  6.     DialogResult = DialogResult.None;
  7.     MessageBox.Show("Invalid user name or password.");
  8.   }
  9. }

I use the logged in state to block some menus on the application;

  1. private void mnuFile_DropDownOpening(object sender, EventArgs e)
  2. {
  3.   mnuLogin.Enabled = !EcoSpace.UserService.IsLoggedIn;
  4.   mnuLogout.Enabled = EcoSpace.UserService.IsLoggedIn;
  5.   mnuChangePassword.Enabled = EcoSpace.UserService.IsLoggedIn;
  6. }

Some objects need to relate to the current user. Add that to the Created method of the class

  1. public partial class SomeModeledClass
  2. {
  3.  partial void Created()
  4.  {
  5.    CreatedByUser = AsIObject().ServiceProvider.GetEcoService<IUserService<User>>().CurrentUser;
  6.    CreatedDate = DateTime.Now;
  7.  }
  8. }

There are many a neat things that can be plugged in as services. I hope this gives you an idea of what is possible.

–Jesper Hogstrom

  • Share/Bookmark

Dynamic firewalls

On my way home today I thought abut all the intrusion attacks and pondered the possibilities to update the firewall automatically.

I get logs mailed from my various systems on a daily basis. Several times a week they are filled with failed attempts to pick up mail from adam, annie, alonzo, bert, bill, caesar, daniel, david… as well as requests for /phpadmin/index.php /phpdbadmin/index.php, /phpsqladmin/index.php and so on.

The idea I dreamed up was fairly simple; either hook onto an existing intrusion detection system (IDS) like snort or write some other simple rules, maybe by analyzing log files from apache; “if an ip# requested 10 non-existing pages in 5 seconds, drop all packets from that source”.

I didn’t get very far in my thinking, before I realized someone else may have already done this. My first search yielded quite a few hits, including some stating it’s a bad idea to auto-block ip# based on IDS rules, mainly because of the many false positives.

However, one guy was right along my thinking with a Dynamic Firewall Daemon. The specs matched much of what I would eventually have set up myself (he said humbly). Other applications in the same area include fwsnort.

On the other hand, this article from linuxsecurity.com states “intrusion prevention is still at its early stage and there is no out-of-the-box product that will perfectly fits your requirements.” – though that was written ages ago (2006 I would guess based on the date of the first comment).

An insightful article from IBM gives some handy scripts, but not quite automation.

I readily admit to not being an expert in package filtering, but I do run firewalls, IDS and open only the ports required. What worries me a bit is that the majority of people out there are unaware of even the most basic facts about how to protect themselves from attacks. And even Pentagon have a problem securing their perimeter…

Before I completely take off on something else, I recommend the OnPoint Radio show on Cyber warfare. Much more high level than mere firewall scripts, but very eye-opening.

Anyway, if you have any experience on dynamic firewalls, open source or commercial, please feel free to share!

–Jesper Högström

  • Share/Bookmark