Why engines and components are not evil but distracting
Posted by David November 11, 2005 @ 10:47 AM
I’ve been following the enthusiasm for engines, components, and bigger plugins from the sidelines for a while now. It’s a subject of very mixed emotions. On the one hand, I’m really glad to see that people get so excited and start dreaming of bigger and better things. That’s passion in the works and its great.
On the other hand, I think these developments are basically another name for high-level components. And you all know how I feel about those. The short summary is that high-level components are a mirage: By the time they become interesting, their fitting will require more work than creating something from scratch.
But I start getting really high eyebrows when I hear of “engines that depend on other engines that can be swapped out with yet another engine”. Even plugin dependencies are dangerously close to something I would consider unfit for Rails. Simply because it encourages a style of development that I find unhealthy.
So this is not a slam against the technical merits or implementation of either engines or anything else in the same boat. It’s a concern that they will distract people, that they will appear as needed, and in turn, that they will take the debacle that was Salted Hash Login to a new standardized level.
Rails is all about making the simple things so easy that you need not abstract them. It’s about making the creation of logins, of access control, of content management, of all these business logic components so very easy that you will treasure the application-specific solutions of your own rather than long for The One True Login System.
So what am I saying? That engines should be stopped? Of course not. But I am saying that Rails will continue to send a signal with what’s included in the core that this is a sideshow project. It satisfies some needs for some people and that’s great. But the goal of Rails is to create a world where they are neither needed or strongly desired. Obviously, we are not quite there yet.
One way of getting there is to do a better job of educating new comers in common patterns. Answer the question “if engines and components are not the way, then show me how!”. So this is a call to all those experts out there. Help us spread the good patterns. Make videos, write tutorials, help newbies on #rubyonrails, answer requests on the mailing list.
And if you have a great idea for an engine, or a high-level component in general, think about this: Is there a way I could abstract a smaller slice of functionality as an independent plugin and then release that alongside a pattern that described how to use it like the component would have done all in software? More often than not, I think you could find this to be true.
Note: James Adam, the creator of the engines approach, has a great post on the mailing list for how he uses engines internally at his company. That’s perfectly cool use. The trouble with high-level components are solely related to making them generic.

”..the debacle that was Salted Hash Login..”
Could somebody elaborate on what was the issue with the Salted Hash Login? I haven’t had a chance to check it out yet, but seemed like the Agile Web Development w/ Rails book recommended it.
As the person who actually wrote it, I can probably guess what David was referring to, since I was almost immediately unhappy that I released it with a few of the decisions I made.
The first was the dependence on the localization gem. Any localization stuff should have really waited until the Rails core supports i18n.
The second was the overzealous use of <% class_name %> substitutions in the generator. It really doesn’t need to make so much of an effort to avoid name collisions.
The third was the heavy use of helpers for the views, which were really there only because of the localization stuff.
The only features I truly needed at the time were the password salts and the email notifications and such. The generator should have stuck to those, and left out the rest.
Thank you David, just thank you.
I sort of disagree here. I think that higher level components are in fact at times a fallacy, but the engine concept seems to make sense. I’m getting ready to launch something new, and I want a blogging component. I can either a) write my own (NIH), b) embed the source from Typo, an already excellent blog, or c) use a Typo engine as part of my application. ‘b’ has some complexity associated with it, though things like svk make that a little easier. I think ‘c’ is the right choice, and the one I’m going to make. I may be wrong, in which case I’ll report on my experience on my blog.
I wish this post would’ve been posted two days ago. I just spent the last two days trying to integrate ModelSecurity (and the SaltedHash login system that comes bolted to it by default) into my application. I took me a good 6 hours just to figure out how the whole thing fit together. The rest of the time was spent trying to figure out how to divest it of the features I didn’t need or wanted to do differently (non-HTTP-AUTH logins, for one.)
I wish this post would’ve been posted two days ago. I just spent the last two days trying to integrate ModelSecurity (and the SaltedHash login system that comes bolted to it by default) into my application. I took me a good 6 hours just to figure out how the whole thing fit together. The rest of the time was spent trying to figure out how to divest it of the features I didn’t need or wanted to do differently (non-HTTP-AUTH logins, for one.)
Finally, two hours ago I just said hell with it and decided that by the time I both figured out and bended SaltedHash to my needs, I could write my own system tailored to exactly what I’m doing, and know it from tip to tail. A svn merge and two hours later and I’m already further along than I was in the past two days of diddling with SaltedHash.
The reason I was going with ModelSecurity/SaltedHash in the first place was because the book recommended I not wright my own login system but use a generator instead. So I looked at the wiki and ModelSecurity seemed to be the most advanced of the bunch. Perhaps in future printings the phrasing in the book can be clarified to put rolling your own in a higher regard? The reason I was going with ModelSecurity/SaltedHash in the first place was because the book recomended I not wright my own login system but use a generator instead. So I looked at the wiki and ModelSecurity seemed to be the most advanced of the bunch. Perhaps in future printings the phrasing can be clarified to put rolling your own in a higher regard.
Matt: I did the exact same thing, only I gave up sooner.
Concerning the book’s recommendation, I wonder if it is not a thing that DHH and Dave Thomas disagree upon?
I think it’s possible to have good prebuilt login code, but it needs to be simpler than any of the current offerings. But still, writing my own was so damn easy that I question the value.
The book says can you “can download” a generator for this stuff. Perhaps that’s being read a bit too frequently as “should download”. I’ll have a chat with Dave Thomas about that.
Larry: Sounds like what you need is simply an application. Not a component you should tailor. I’d recommend simply installing an running that application on its own.
This is a serious philosophical debate. I’m glad to hear David’s stance, because it encourages self-sufficiency / roll-your-own behaviour which is rarely encouraged amongst programmers. Why reinvent the wheel? Because you can get one that does exactly what you want and no more.
The pitfall is that most programmers will not be great programmers, especially as RoR moves into the mainstream. Of course standardized engines and frameworks will be necessary, but I’m glad to see that Rails will continue to be focused around core development processes and not providing a library of components.
DHH
It was probably the combination of these two lines in the Rails book that led me to mistakenly believe that the book was recommending using the login generators
Footnote pg 119 You can download Rails code generators which will write user management code for you. Search the Rails wiki (wiki.rubyonrails.com) for login generator. The Salted Hash version is the most secure from brute-force attacks.
pg 130 The Rails generator facility can be extended — folks can create new generators for others to use. If you look at the page that lists these add-ons, you’ll see at least two off-the-shelf login controllers, both with a lot more functionality than the one we just wrote. It might be prudent to experiment with these before creating your own user management system.
But talented Rails developers are a very valuable commodity, and will only become moreso.
Why go to work for a poor non-profit when you could make $50/hr contracting for an insurance firm?
High level components are a way to lower the barrier to entry for people with less facility with computer science. And that could have the effect of bringing the benefits of web development to more of the socially responsible organizations that truly need it.
See Obie’s post:
Serving the Long Tail: Developers of Usages http://jroller.com/page/obie/20051021
What does everyone make of his John Henry project?
http://www.steeldriven.org/
Marcus: I agree. But I think the way to deal with that problem is by teaching man how to fish. Not by just giving him a fish.
Less is more:
No components or engines:
Abstract a smaller slice of functionality as an independent plugin and release that alongside a pattern that describes its usage, like the bigger component would have done.
Is there a site for RoR plugins which has a pattern + discussion page for each plugin?
Hey, less is more suits the small plugins vs heavy components argument too.
I get the same uneasy feeling when people start to talk about building generic CMS tools and photo galleries and groupware and whatnot on the mailing list. Sure, maybe those things are needed in places, but trying to build them in some abstract general-case ways only winds up providing a solution to some very non-specific problems that no one in particular has.
Much better to build a solution to YOUR problems, and then as you optimize and generalize w/in your application you can extract any bits that might be usable elsewhere and get them into either the rails distribution itself, or a plugin/engine/whathaveyou.
I too needed a login system, saw the reference in the book to the Salted Hash stuff, and started figuring out how to incorporate it. . . about 3 hours later I flushed everything in frustration with an “svn revert”. After another 4 hours I had written the whole thing myself, complete with email verification, salts, forgotten password email messages, and the works-
and it was exactly the way I wanted it. In other words: as David said, the mechanisms are already in Rails to make login systems easy (really easy) to do-so easy that it ended up taking less time to write it from scratch than it was going to take me just to learn to use someone else’s, and then coerce my application to work with their way of doing things—and even then it wouldn’t have worked the way I really wanted it to.The philosophy of providing the tools to make it easy to build high-level functions, rather than generic functional modules themselves, really does work.
David: I hadn’t considered running the app as a standalone, that might make sense. My only concern would be if I wanted a high level of integration. Instead of having a blog at blog.mydomain.com that’s separate from my site, I may want that functionality throughout the site. Certainly a good suggestion though, and I’ll probably try that first in the spirit of doing the simplest thing that could possibly work.
So to summarize, maybe I sort of agree with you now. How’s that for non-commitment?
I certainly agree. I’ve been looking around for general php cms solutions for my website because I didn’t want to take the time to write my own. Finally, I just bit the bullet and wrote my own. A few hours later, I had working solution for my website. I spent less time writing the darn thing that I did trying to find something that would fit my needs. Not to mention the fact that I finally got down and dirty with RSS to learn how to generate it myself (not that hard really).
I had tried several different content management systems and bloggin systems, but none of them fit my needs. I was looking at heavily modifying them to get what I needed. No doubt, I would still be working on that had I not taken the path that I did.
I certainly agree. I’ve been looking around for general php cms solutions for my website because I didn’t want to take the time to write my own. Finally, I just bit the bullet and wrote my own. A few hours later, I had working solution for my website. I spent less time writing the darn thing that I did trying to find something that would fit my needs. Not to mention the fact that I finally got down and dirty with RSS to learn how to generate it myself (not that hard really).
I had tried several different content management systems and bloggin systems, but none of them fit my needs. I was looking at heavily modifying them to get what I needed. No doubt, I would still be working on that had I not taken the path that I did.
sorry about the double post. shouldn’t there be some sort of notification when a comment is successfully submitted?
Daniel, the greatest programmer of alll.
DHH OPINIONS ARE THE TRUE PATH TO NIRVANA! DHH OPINIONS HAVE BEEN THE CHOICE OF EDUCATED AND IGNORANT ALIKE FOR CENTURIES! DHH WILL NOT CORRUPT YOUR PRECIOUS BODILY FLUIDS!! DHH MAKES THE SUN SHINE AND THE BIRDS SING AND THE GRASS GREEN!!
I too have taken the SHLG and LG out for a spin. I too am going to throw them away.
Hours wasted??
For me, No. I learned a lot looking at the generated code.
I now have a much better idea of what I need to accomplish on my site with respect to authentication and authorization.
Thank you, David.
I’ve noticed this as well, glad that you agree. The engines are starting to feel a lot like J2EE development, not cool.
Wow, excellent post David.
I totally agree. When I started looking into writing my first application I considered using the salted-hash generator, but then I realized, wait a second … Rails is designed to make it relatively easy for me to make my own user authentication system and then when I’m done, its mine. I’ll know it inside and out and if I need to modify it or extend it later on, there will be no googling necessary to try to figure out how. That’s why I was so excited about Rails in the first place.
The problem with generators and components and things along those lines is that they are supposedly plug ‘n’ play solutions for everybody. But we all know that if you want a really good application that’s specific to your purposes, it can’t come from something built for everybody. They don’t do 100% of what you want them to, they do 75% or 150%.
The plugin architecture is plenty adequate and I’m sure there will be some improvements to it over the long term. But I hope that we in the Rails community don’t lose site of the fact that Rails is so great because it allows you to build everything you need from scratch with relative ease.
One thing that would be very helpful is a Rails HOWTO video about how to create a login and access control system without using any of the generators or plugins or “engines.”
I think the rails developers should take note of the large user base interest in a login tool, even if it doesn’t entirely fit the rails paradigm.
Writing login systems is drugery. It only makes sense for newcommers to look at the CRUD generator and go WOW, then expect to find the same sort of support for another common website development task, logins.
It would also be easy to write initial CRUD, but it’s so nice to be given a foundation to begin with. A solid login foundation would provide much the same benefit and be more intuitive to newcommers.
I agree with David’s opinions on high-level components, but I’m currently building my own login system as an engine for internal use. Why?
First and foremost, I want to make sure I have a clean interface between the user authentication bit of my app and the rest of it, and I want to separate out the tests and documentation so they don’t clutter the core of my app.
Second, I want to share the authentication code between a few apps that I’m writing that do have similar needs and may want to share user data.
Third, I want something that I can use as scaffolding. If I need a quick and dirty working user system I can plug it in, and then I can customise or rewrite when I want more functionality.
So, while I think that the ideal of generic high-level components doesn’t work, the ability to segment off parts of your app and share them between a couple of apps is still useful.
I’m glad that DHH has clarified his view on components in the Rails world. I comes a a perfect time for me. But it leaves me with more questions about how do work the Rails way.
Suppose I write an integrated login system in one application that would be perfect for 10 other applications. Copy and paste x10?
And then what if I upgrade one and want the upgrade in all eleven apps? Copy and paste x10 again and hope I don’t forget something in app #7? Isn’t this the reason the Rails framework has been separated from my app code?
Authentication does seem like a generic part of an application to me. I wonder how widely people’s needs really vary or if the I-have-special-needs attitude is really unfounded.
I’m new to the Rails world. I want to go with the flow and do things the rails way. And although I obviously can’t demand more wiki info, I can say that the amount of information about plugin development best practices and philosophy in the wiki leaves me wondering what to do.
the problem with large granularity 80% solutions is that the 80% they do is never the 80% you need.
that means if you’re going to try to use some sort of component based approach, it needs to be an open box that you can modify or extend somehow to fit your specific needs.
but as soon as you do this, you now have an integration problem every time your external dependency changes, because you’re inside the abstraction.
you only get the benefit once. from then on, it will take as much effort to maintain and improve that functionality as if you were writing the componant yourself, if not more because it’s some else’s code you don’t know.
the alternative is to close the box, and rigidly use only the functionality the componant gives you.
There’s one thing that really puzzles me after reading DHH’s stance:
http://dev.rubyonrails.com/changeset/2967
If plugins ought not to be higher level components why has a change been made which (apparently) allows them to mess with routing?
Perhaps I’m getting the wrong end of the stick but it strikes me as odd.
I think there’s a huge confusion here between ‘generic’ and ‘simple’. The login engine has never tried to be generic. It’s ridiculously simple, that’s all. It’s very opinionated, too. Almost none of its behaviour is dictated by configuration. Engines are only “plug `n’ play” as much as Generators are “script/generate `n’ play”.
Jason: engines let you make your modifications external to the abstraction.
Peter: it’s a brave new world, don’t be afraid to get your hands dirty.
Marc: “supposedly plug ‘n’ play solutions for everybody” – why does everyone think this? It’s no more true than saying the same thing about the SHLG, and who believes that? I’d encourage you to look at what ‘flexibility’ actually means in terms of engines. It’s not configuration, and it never has been.
PJ: “engines are starting to feel a lot like J2EE development” – This comment puzzles me the most. Why? Where are the EJB-esque XML configurations?
If you have 15 minutes to spare, you can read this:
http://rails-engines.rubyforge.org/wiki/wiki.pl?OhGodWhatHaveWeDone
... but please – enough debate! If you don’t like engines, don’t use ‘em. Just please don’t perpetuate misunderstandings about what they actually are.
Allow me to reiterate me support for Adam’s original goal: Sharing code within your own organization. To 26 and 27: These are fine uses of engines or plugins!
What I’m arguing against is thinking that because you could make logins work generically for your own applications, that it’ll make a great fit for everyone else.
I’ve found that abstraction at an API level is successful for infrastructure-level pieces. Higher abstractions than that are called applications.
Anyone who sells their plugin as being perfect for everyone is delusional or naïve. On the other hand, anyone who believes that kind of hype probably needs to learn from their own mistakes.
I think we’re done with the One True Way debate. Nothing will ever be a “great” fit for everyone’s application, but we might be able to provide a number of good example starting points to base your own systems on. I believe this was one of David’s original points – show how it could be done, rather than dictate how it should be done. My repackaging of the SHLG as the “LoginEngine” was no more a declaration of best practices than the original SHLG itself (i.e. not at all).
If we can give developers this kind of hit-the-ground-running benefit in such a way that lets them get their application up and running quickly and then develop and migrate to their tailored code with as little hassle as possible, mores the better. If it turns out they don’t need anything more (and this will happen from time to time, and perhaps more often that you’d think, especially when prototyping) then that’s cool too.
So: if someone can show that using an engine to achieve this end is an objectively poorer solution than a using a plugin or generator (or heaven forbid asking Rails newbies to work from first principles), I earnestly and sincerely want to know. All qualified and constructive criticism is appreciated.
If, on the other hand, this is really a thrashing out of the politics & philosophy surrounding shared code, and a reaction against Lovecraftian nightmares of grafted bits of applications kludged together in a grotesque Frankenstein fashion, lets acknowledge it as that, and only that; a cautionary tale, not a crusade! We will all feel quite justified in pointing at any monsters that are subsequently produced with a knowing “I told you so”.
James, I mention it feels like J2EE development because the engine concept reminds me of adding components like the Spring Framework, Hibernate, JSF, Acegi Security, and so forth to get started with any sort of J2EE project that I’ve done in the past.
Rails certainly should stay true to its core and avoid getting too involved in components and such.
However, I would echo Marcus’ sentiments, and also question the elitism I see in some of the other posts about “rolling your own” versus using existing solutions.
Not everyone is a programmer. That will never change. Not everyone works in the corporate world. Not everyone has the financial abilities to hire programmers. Not everyone has the time to write there own program. There will always be cases where it is not practical to do everything from scratch.
Most non-profits, NGOs, political campaigns and organizations, have serious constraints when it comes to time in money. They don’t need the perfect solution. They just need a solution that works.
One of the major problems I see is how little actual open source layer there is in the rails community. How many times have I read posts where people have talked about how easy it is to do this or that, and yet they keep the specifics to themselves. There aren’t very many good examples, and except for typo almost no open source projects.
It may be easier for some people to do everything from scratch than to spend the time tweaking other people’s work. But, there are also times where one person’s solution may work perfectly for somebody else.
What happened to the spirit of open source?
If sharing code was the goal of open source, why are there so many template engines for PHP?
Sharing code between projects isn’t the spirit of open source, being able to change something without having to ask permission from the original author is the spirit of open source.
But programmers should be.
Then, in the spirit of open source, they should be able to take an existing project, for free, and use that. If they need changes, make those changes themselves, or ask someone else to make them.
Talking about “from scratch” means nothing when you are talking about Rails. You never start from scratch: you’ve got Rails! Written in a very high level language: Ruby.
If you want “from scratch” to say you are only just starting to write code, then you will always start “from scratch” regardless oh how many layers of engines and generators you use – because you won’t have written them.
Dan, I don’t recognize your view of open source in Rails. I see i2, Colloboa, Hieraki, and lots more. Have a look at the open-source app list
And I agree that not everyone is or should be a programmer. These people needs applications, not components.
Also, if its applications you’re really after, then it shouldn’t matter too much which language/framework you’re getting them from. Sure, I’d love to see it all from Rails, but its certainly not a necessity.
I agree with the problems of high level components; the arguments against them here are well reasoned and look as though they come from experience. However, everything that I’ve read about security tells me that it is very easy to mess up things like salted hash passwords in such a way as to make the system needlessly insecure. If the base functionality of this were encapsulated into a plugin then these problems could be alleviated to some extent.
My knowledge of salted hash passwords comes from a couple of blog posts and the wikipedia article. While the core logic of the process doesn’t seem that difficult, I’ve been warned enough times against rolling my own security solution that alarm bells are going off in my head about attempting it. Should all Rails developers be independently rolling their own security solutions for the same problem?
That said, I tried to integrate the Salted Hash Login Generator into an app one afternoon and made little to no progress, in no small part due to the apparent absence of documentation.
Perhaps a simple plugin that lets one do something simple like
acts_as_salted_password :password_column_name
and includes gives a few helper methods (and a bit of documentation) would be minimal enough to be useful for most projects.
Hi,
“I think the rails developers should take note of the large user base interest in a login tool, even if it doesn’t entirely fit the rails paradigm.”
“Writing login systems is drugery. It only makes sense for newcommers to look at the CRUD generator and go WOW, then expect to find the same sort of support for another common website development task, logins.”
I have to agree with the others commenting on logins. Having recently developed an app with Rails, the one thing I was surprised to find missing was a simple login system, with secure storage of hashed passwords. Instead I ended up using one of the generators and adapting it.
“I’ve found that abstraction at an API level is successful for infrastructure-level pieces. Higher abstractions than that are called applications.”
What I expected was a standard for storing/user login and hashed passwords, plus an extensible user type (reader..admin). Possibly with some helper routines for limiting access à la model security. This would then be extensible as ActiveRecord is for other application specific attributes/code. Nothing more, and nothing less.
These things are of course quite quick to do, but why reinvent the wheel and possibly introduce bugs and security issues when everyone is doing the same things? The smorgasbord of different options for login we currently have would suggest that this is a commonly felt need – does login really deserve to be called a high level component along with forums, blogs and the one true CMS?
While the emphasis on keeping high-level components, and the aspirations that go with, out of the core rails is a laudable one, every non-trivial web app includes user authentication; just as every non-trivial web app includes database abstractions, separation of logic from views, and email to and from the server (all of which Rails currently provides).
Great discussion! Forgive my newby ignorance, but while I agree in principle to DHH’s comments, I’d say login/model security is absolutely the wrong example!
The flaw in the argument, to me, is that DHH assumes the website will use a database (hence includes ORM in Rails) but assumes there will be nothing more granular than a simple login (‘all or nothing’ security) to protect this data! It’s no surprise to see this discussion centred on login and security – I reckon 95% of all Rails users need it. Therefore why not implement it as part of the framework?
I’m heartened from all the posts here to see my experience replicated amongst so many (but perhaps it would be better if DRY was extended to DREEE – don’t repeat everyone else either!). I too have tried ModelSecurity, played with it and given up, and hope now to roll my own.
To me the main flaw with ModelSecurity is that it doesn’t support user roles (you are either admin or you’re not…). The thing I like about Rails is the DRY philosophy, and I’m pretty certain the same kind of thinking can be adopted to build a granular security model in to the framework with minimal coding. I’m literally just starting now… (and I may be some time…!) but I’d be glad to start kicking ideas around with anyone!
What is interesting for me in the Engines debate is not the fact that you use components per s.e., but the fact that you might be able to tie-in a number of Rails applications in one concrete website. Granted, currently you have “one site, one app” philosophy, but sometimes you are really better off running a weblog, a forum and something else but sharing at least the login cookie between them. Without invading too much into the applications themselves (and without rendering one of them inside the other) but instead providing as little glue as necessary so that a user can change his password Once And Only Once instead of doing it in all tools every time.
I’m 200% in agreement with McNewby.
The majority of “applications” on the web require security. Security should always be extendable (ie, have a role/permissions matrix).
Its core to so many applications. It makes total sense plugging it into Rails core.
The fact that ActionMailer exists without it is somewhat bizare.
I’d hazzard a guess that most real world applications use multiple access permissions and an authentication systems. If they dont, then their authentication system is flawed (it might not be a requirement now, but when it is … game over man).
I’m 200% in agreement with McNewby.
The majority of “applications” on the web require security. Security should always be extendable (ie, have a role/permissions matrix).
Its core to so many applications. It makes total sense plugging it into Rails core.
The fact that ActionMailer exists without it is somewhat bizare.
I’d hazzard a guess that most real world applications use multiple access permissions and an authentication systems. If they dont, then their authentication system is flawed (it might not be a requirement now, but when it is … game over man).
Silly double post :( appologies.
Somewhere between the extremes something very useful lies. Big & bloated is bad, non-existant can be bad too. Something that helps show us the way, that would be very good.
It’s no surprise to see this discussion centred on login and security – I reckon 95% of all Rails users need it. Therefore why not implement it as part of the framework?
I think the reason why is because no login/authentication system will work for everybody all the time. Its something that should be custom built for a well-built app. When I went to build my user authentication system for my app, I found that none of the pre-built services came even close to doing what I needed it to do.
ActionMailer and ActionWebService provide services for a standardized part of the web. Its something that’s relatively uniform across web apps.
I think time and effort would be better spent writing guides, blog entries, etc. to help people better understand the Rails architecture so that they can easily build their own user authentication system.
Last spring, I bought myself a boat. First thing that happened was that both batteries went dead. My father-in-law lent me his battery charger and with the batteries fully charged I asked him if I could borrow a monkey wrench to install the batteries (unfortunately I didn’t have my own tools there at the time). He objected to the use of such a tool, trying to persuade me into bringing his full set of tools to find the ones that fit perfectly. As you may know, batteries tend to require two wrenches of different sizes.
“It may seem easier now, just to bring the monkey wrench and save some carrying. But just think of the feeling you’ll have once the thing slips, and you know this decision will haunt you every time you’ll be changing batteries”. Needless to say, I brought the full set of wrenches.
There is no one-size-fits-all. Really.
To decide whether something goes into core, we are driven by two core principles: Is this something that’s useful by the many? Is this infrastructure or business logic?
Login/authentication may satisfy the first, but fails miserably on the second. It is very much business logic and very much not infrastructure. It depends highly on the application its designed for. Thus, it’s a terrible candidate for core.
We only seek to include in core those elements where the abstraction can serve most people most of the time. Login/authentication is not such an abstraction.
perhaps a useful addition would be the possibility to encrypt fields within the DB, based on a key within the Model, similar to the :serialize option ?
e.g.
:encrypt => ‘password’, :salt => ‘4380h93eg’
Where can we learn more about the “engine approach”? James has me interested because my company may be going through something similar and I’d like to see how others solved it. Google is of no help, and there aren’t any other links about it.
Thanks for the insight into core inclusion standards. I offer that alot of authentication is infrastructure. User / Group authentication has been infrastructure in Unix from the beginning. Role based authentication could be a valuable model for many websites. Clearly, how users sign up, how they are notified, and how permissions are edited are business logic issues. But the act of verifying a userID and password and checking their permissions to perform each method seems very infrastructurish to me.
Possibly you see this as too trivial to be an issue. From the community responses I see, it is much in demand.
Core elements to perform these functions, along with scaffold to add users / roles / permissions seems like a very powerful tool to me.
Please don’t let these petty issues distract you from the important work on 1.0!
I really like the
idea for a plugin, seems pretty useful.
I’ve used the Login Generator (never the Salted one, bad for my blood pressure I suppose), but heavily modified it for each application. Some apps require different security models. When it comes down to it, I like the idea of grabbing a plugin or using a generator as a starting point, but you almost always need to customize it. At the very least though, you tend to learn something from the code.
Anyways to each their own.
I like the idea of having some kind of security infrastructure available (like ModelSecurity, minus the user stuff), but I have to agree with DHH that a Login system is a little out of scope for the core.
I think the reason for this is that for login information to work, you have to be storing it somewhere. Thus, it’s much more tightly coupled to a data structure than the rest of the core. However, providing “hooks” for security restrictions might be more in line with the philosophy behind Rails.
David’s quote about learning to fish is the best so far.
Usually these tools (like Engines, etc) will be most useful to their creators, for their own specific needs.
But, maybe, someone else will find your tools useful as well. So, no harm really in realeasing them into the wild if they do the trick.
Sorry to pimp my own wares here, but if you are looking for basic login functionality and an OK looking Rails app theme to get you started, check out QuickStart Rails:
quickstart-rails.menlopark2.com
That site is actually a self-running install of QS Rails.
If you have Subverson already insalled, all you have to do is run a simple svn export command to get up and running quickly w/ a new Rails app, basic login code included.
Be sure to “rails .” in the ./trunk/your-app dir to make sure it’s running the latest rails after you export the tree.
“Is this something that’s useful by the many? Is this infrastructure or business logic?”
“Login/authentication may satisfy the first, but fails miserably on the second. It is very much business logic and very much not infrastructure. It depends highly on the application its designed for. Thus, it’s a terrible candidate for core.”
Perhaps I’m missing something, but how is inbuilt granular extensible security NOT infrastructure? Its infrastructure to provide business logic for the majority of applications.
Wether or not you supply a login screen, and the salting stuff, now thats a different story…
Lets compare role/permission based security vs something like scaffolding. Scaffolding does not pass either of your “core” questions. Its not really even useful by the masses other than being like a “hello world” tutorial thats built into your project. Its suggested NOT to use it. Its “cool” and works for the videos, and perhaps thats why its included, for the WOW factor.
“We only seek to include in core those elements where the abstraction can serve most people most of the time. Login/authentication is not such an abstraction.”
Certainly granular role/group based security is, and should exist by default in every project.
Can you enlighten me?
forgive the buzzwords used above :)
I just posted to the rails list about this – I think DHH used to working in a products company, not a client services company. He does later say that he thinks it’s great to share code within an organization, etc.
Manuel ported ActiveRBAC from the RBAC code we developed in binarycloud specifically so we could have a sophisticated system that would do what we needed for our own projects. If you look at the source and it doesn’t do what you need, modify it, hopefully tell us and contribute, or don’t and move on.
Engines seem to me to be a perfect fit for applications that are typically embedded in a site: Forums, Blogs, Wikis, etc. Makes very good sense if they all can manage routes for themselves and plug in to a full rails project.
Typo is an application, I don’t want to write my own blog for use in a project: I just want to be able to embed Typo in my application template and override some of its views. Would be perfect.
moo,
_a
What is the difference between plugins, engines and components?
I don’t mean on architecture level but more on “what can engines and components do that plugins can’t?”
I’m ‘new’ (read: doing my first project with Rails) to Rails and for my project I need a simple login system. Any advice?
Thanks!
Lesly: http://rails-engines.rubyforge.org/wiki/wiki.pl?ComponentsPluginsEngines
Lesly: http://rails-engines.rubyforge.org/wiki/wiki.pl?ComponentsPluginsEngines
Thanks !!! :D
Perhaps a lot of Rails users are people looking for a way around learning how to program. Higher-level components are the logical next step to this line of thinking.
There will always be solutions for these people but they will never be as good as something a skilled developer can build custom. That’s my take.
Login and permissions is not “business logic” on my powerbook. it is very much infrastructure.
I guess I’ve had the opposite experience from most of the posters here. I’ve built six large scale web applications, and probably a dozen tiny ones, and the login systems I created for each application were nearly identical.
Clearly there’s two camps of thought here, but I’m still very much on the side of granular permissions based security model being infrastructure, not business logic.
For me the failure of the existing ‘login’ plugins is that they include too much business logic and not enough infrastructure. Whether the system sends an email to those who have forgotten their password IS Business logic – and also makes these plugins unusable to most.
However, from an infrastructural perspective, I like the thinking of ModelSecurity – in as much as permissions should at least begin in the Model (and hopefully ripple out to the UI). It should be possible to develop Rails such that permissions can be automatically ‘discovered’, e.g. for every attribute, there’s only three options: no access, read, write. Likewise for each method, there’s only two: can run, can’t run…
This is probably enough for now. Having now downloaded the Rails source, I shall have a play! If ever I make any break through, I’ll report back on the ‘Community’ wiki pages (I need to investigated existing implementations too, which I’ll pull together on the wiki, probably sooner than any actual code of my own).
Anyway, enough argument! It remains for those of us in the ‘infrastructure’ camp to make the most compelling argument possible – get the thing built and make it indispensable to all!
It would be very interesting to get together some of the more mature/well-written login/authentication systems that are out there, so we can compare them side by side and try and determine any common features.
This might at least begin a push for a ‘Good Practice Guide for Authentication’. The difficulty for newbies, or indeed anyone approaching login/authentication systems for the first time, is simply ‘where to start’. There are many ways of implementing such a system and you don’t want to mess up your security !
Perhaps the wiki is a good place for this?
To me, security consists of two layers. One is low level security (core components) which provide a “security infrastructure” for a given framework itself, and the second is “Application level” security which is built upon core components provided by the framework.
If somehow Application programmers could build upon the core primitives provided by the framework, then it would be more consistent. And upgrading would become a little easier, if what you are doing at app level is essentially calls to the core security primitves.
So, “core” or “Infrastructure” security provided by the framework, and “application security” built upon and extended by the RoR “app developer”.
I have seen this in ERP software like Peoplesoft where the core security primitives (User Profiles, Roles, Permission Lists) are provided by the framework (what they call PeopleTools) and the security at a particular implementation site is developed by an implementer combining those primitives to tailor the security for the application being delivered by applying the business rules to create a “custom” security matrix for the client’s need.
It would be a major P.I.A to start creating security from scratch for a major client based on their business needs. I’m not suggesting that RoR’s intended audience is ewwwwwje corporate clients or anything like that.
I think the end product delivered to the clients may have needs for a custom security model, but I think a custom security model can be delivered using security primitives provided by the framework (combined in different ways), and every time we know that it is built upon a consistent base and not built from scratch for that particular client.
In order to determine whether such core security primitives are deserved of the RoR ‘core’, we require to consider them in more detail. I.e.we should specify examples of what these might manifest themselves. We can then easily ascertain if they pass David’s tests, namely :
“Is this something that’s useful by the many?” and “Is this infrastructure or business logic?”
Ok – my turn first – I believe this might be a useful addition to ActiveRecord :
encrypt :column => “password”, :salt => “ajshjkh”, :method => “XOR”
It would work in a similar way to :serialize.
any ideas people ?
Jim
I think that this is a great suggestion… it will save us a lot of time :D
It will rock even without the method-hash (I think that this is not really needed)
I suggest that we use the strongest encryption standard available now…
(not MD5 !!!)... SHA-512 (at least ‘normal’ SHA) rulezzz.
http://en.wikipedia.org/wiki/SHA (for more details about SHA variations)