Back In The Saddle
January 13, 2011 Leave a Comment
I haven’t posted anything in over a month. A lack of posts should not be construed to imply a lack of progress, however. On the contrary, over the past month I have refactored and rewritten large portions of WPISuite’s code to make it capable of hosting server-driven modules. In the process I also performed a general cleanup on the areas I was working with. The result is, in my opinion, a much better code flow. This also enabled some small, but significant, improvements to the user interface (loading bars, anyone?) and the unwinding of some especially nasty hacks (ding, dong, WPISuiteMessager is dead!). There are a lot more things I’d like to do (ActiveObjects must die!), but the client is now capable of doing what we need, our time is limited, and I have a lot of other, more important items on my to-do list.
There are three large items currently topping this list:
- Server configuration. Up to now, we’ve simply relied on an XML configuration file for this, but that’s simply not sufficient. For a server that can have (in theory) as many nodes as you can afford the hardware to support, uniformity of configuration is a big deal. I’ve come to the conclusion that as much configuration data as possible should be stored in the database. This will enable support for item two on my list…
- Server Administration module. Ideally, I’d like to build a module for the client capable of displaying the state of and configuring the entire server: every node, active or not. Whether or not this will come to pass, I can’t say. At minimum, this module should support the same tasks as its standalone counterpart, the System Administration module, does. Due to ActiveObjects hack-arounds, it’s not feasible to just write a new controller and reuse that GUI. Although I probably wouldn’t do that even if it were possible, because I have some HCI problems with the design.
- Server permissions system. Over break, I probably spent about a week in total researching and contemplating this problem. I’ve concluded that the usual suspects like RBAC, ABAC, and capabilities aren’t going to work for us. Not smoothly, at least. Capabilities is designed to solve a problem we don’t have, RBAC treats permissionss as being largely orthogonal to your domain model, and ABAC is concerned with attributes of the user and the resource rather than attributes of the relationship between them. That last point is the most important one. I realized that when we ask the question, “is user X allowed to do action Y on resource Z?”, the answer is always in our object graph, and it’s always in our edges, not our nodes. That is, the answer to the permissions question is arrived at by asking the question, “what is user X’s relationship with resource Z, and what are the attributes of that relationship?”
When I got to that point, I was suddenly reminded of a short piece by Martin Fowler that I had read a while back. He discusses the problem of having an anemic domain model and I realized that was exactly our problem. Well, more accurately, the problem is that we don’t have a domain model, just a data model. A lot of people tend to use these terms interchangeably, but they’re actually two different things. The data model just defines the structure of your data, i.e. how it’s persisted. The domain model is a layer on top of the data model that organizes your data in a way that makes sense for your application and enforces your business rules. As Fowler states, a lot of people think adding business logic to your model is something to be avoided. I think that’s probably because they’re trying to add the rules to their data model rather than their domain model, and that is a bad idea. But, as Fowler states, if you don’t put your business logic into your domain model, then you’ve incurred the problems of the object-oriented paradigm without taking advantage of any of the benefits, and you’ve slidden into the procedural paradigm.
The point of that whole story is that security rules are just as much business logic as anything else. Our objects need to encapsulate behavior as well as data, if for no other reason than that I really don’t want to write the same permissions and validation logic in two different places. I’ve actually already done this on a smaller scale with our client configuration code. The objects we throw around are actually wrappers that encapsulate the underlying objects provided to us by Commons Configuration. They provide validation methods and build additional data based on the configuration data. For instance, the ServerConfigProfile iterates over its modules and determines if legacy support is required or not, along with building a set of all the exports the server needs to make available. These are later used by the ServerFunctionDelegate to make sure the server actually provides said exports before the main GUI is instantiated. If it doesn’t, login fails and an appropriate error is displayed.
Well, that was a lot longer than I expected (as usual). I haven’t decided which problem I’m going to tackle next: the permissions or the configuration. The team is meeting in about an hour to discuss the project. We’re going to be focusing on the GUI for the Submission System module, but we may talk about these other issues as well if there’s time. I may make another post after the meeting depending on what we accomplish.