Page 2 of 20

Posted: Tue May 16, 2006 10:31 pm
by alex.barylski
Ambush Commander wrote:PEAR::Auth - When I was a young grasshopper, I attempted to use Pear::Auth. The login callback function didn't make much sense to me. Furthermore, the class attempts to both authenticate and authorize, and fails miserably on the latter. General consensus out there seems to be don't use it.

PEAR::LiveUser - Supposedly it's a bit better, but it's got far too many dependencies. Without access to a PEAR installer (if there's one thing about PEAR I love, it's the installer) on the webhost this authentication system will be installed upon, it's a pain to maintain PEAR libraries (yes, I know they're optional, but don't tell me you're not going to have it interface with the database). This applies in general to most PEAR libraries. Plus is Beta, which is another strike against it.

PHPGACL - An interesting permissions system, but nothing too amazing. It requires a few other weighty third-party packages, and uses quite obscure terminology (if I was a non-tech savvy admin, I'd be lost in the jargon). And it's a bit overkill for what I have in mind.

I agree with Nathaniel: if you understand the problem, a homegrown solution will be simple and efficient, and perfectly suited to the task at hand. Furthermore, for one-man developing teams, it's beneficial that the developer knows about the component intimately, rather than having to learn a third-party system.

If I was looking for an authentication library, I would not be looking for so mcuh a library that let's me go $a->isUserAuthorized() but rather a toolkit with simple "components" that every authentication system has, and put them into a greater interface for the particular application being designed.
The login callback function didn't make much sense to me
Agreed...
Furthermore, the class attempts to both authenticate and authorize
Oh really? I was under the impression it only did authentication...

Both should be kept separate...after some consideration and arguing...I would strongly support that point...

The problem is Authorization is pretty simple...

Code: Select all

$ret  = checkPermission();
if($ret)
  echo 'Execute code';
else
  echo 'Your not allowed ';
So I can see why one would try an amalgamate the 2 functionalities into one class...

I did...round robin anyways...and it wasn't due to lack of experience in OOP or designing systems...but the lack of complexity in an authorization class...

The complexity may change, as I haven't started on the authorization class yet...but from what I can tell...it'll stay fairly trivial...
but it's got far too many dependencies. Without access to a PEAR installer (if there's one thing about PEAR I love, it's the installer) on the webhost this authentication system will be installed upon, it's a pain to maintain PEAR libraries
This I what hate about PEAR...dependancies...it's what I hate about Linux too...

Thats the one nice things about proprietary systems like Windows...sometimes less options are a nice thing :)

It's like eating at subway...way to many options...I'm just hungry...feed me :P

Thanks for the feedback

Cheers :)

Posted: Wed May 17, 2006 1:11 am
by Christopher
Everah wrote:I kinda like the idea of a code-by-group thing. I might want to get in on something like that if it ever materializes.
I think it might produce some interesting code. My goal with putting some rules on it was to provide a structure that would prevent "design by committee." That's why I suggested that one person owns the code and a small group vote on design decisions as needed. The goal should be forward progress, so a voter should voluntarily fork themselves out of the process if they get too out of sync with the code owner. I think it is better to let the thing run its course than to churn on disagreement. A new process with different decisions can always be started afterwards when everyone is a little more knowledgable on the subject.

Posted: Wed May 17, 2006 3:10 am
by Maugrim_The_Reaper
It's funny seeing the Homegrown vote expand while all other options remain at zero...:). I rarely use PEAR modules, the sad fact is that I am typically restricted to shared hosting for personal projects and therefore PEAR is rarely a good option. I do use them in other projects, but I've never been a fan of the auth classes. PEAR has its highs and lows.

I'd be interested in seeing something emerge, so I'll play along...

Posted: Wed May 17, 2006 8:29 am
by Nathaniel
aborint, I've never done either "code by committee" or what you suggested, but your idea sounds good.

So tally one vote for aborint's rules.

Posted: Wed May 17, 2006 8:49 am
by Maugrim_The_Reaper
2...

Posted: Wed May 17, 2006 10:35 am
by RobertGonzalez
3...

Posted: Wed May 17, 2006 12:11 pm
by Christopher
Ok, so we have a project to build an "Authentication System" in PHP with Ambush Commander as the Coder/Designer and Nathaniel, Maugrim_The_Reaper, Everah and myself as Voter/Designers -- which is an odd number so no ties, that's good. I assume we go along until we disagree, that's when we vote, and we generally defer to Ambush as it's his baby.

Ambush Commander should drive the process as he was the instigator. We probably first need to define the scope of the project and the terms (to clear up the whole Authentication, Authorization, Access Control namespace confusion). So Ambush, can you describe more specifically the thing you have painfully built twice and are hoping that three's a charm?

Posted: Wed May 17, 2006 3:01 pm
by Ambush Commander
Okay.

The first version was incredibly naive and buggy. Essentially, it used flat-files and unhashed passwords, and you'd use it by calling authenticate() to determine whether or not the user was authenticated, and adminperm() to determine whether or not the user had admin permissions. Furthermore, there was no way to add new users.

The second version was a quite a bit better, but was bogged down by an implementation that I really had no clue about (intercepting filter). Furthermore, due to the Unit of Work that was also hanging around, it had some weird behavior with remember me. And, to top things off, once again, no way to add new users.

I want to draw attention to the very first architectural decision we will have to make for this system: where to store the answer to "Is this user authenticated?" The first implementation relied on the calling code to pass around return value of the function, which was extremely cumbersome, as it would end up being passed through many layers without actually being used.

The second version added a Session object to the Registry. The registry would then be called like:

Code: Select all

$REGISTRY =& Registry::instance();
$SESSION =& $REGISTRY->getSession();
// do stuff with SESSION
The registry is supposed to be the "correct" way to globalize values, but these two lines were incredibly cumbersome and unpopular (they also appeared all over the application). Furthermore, the SESSION object stored a lot more information then it really needed (to be honest, it basically was the permissions manager).

There really isn't any catch-all way to do this, so I propose that the actual propagation of who the user is and whether or not they are authenticated be offered either optionally or not at all.

Now, personally, I'd like to see a sample implementation to base my system on, because the question is two fold: 1. where is it stored (globals? singleton? bubbling?) and 2. how much information should accompany the barebones user_id that identify the user?

Posted: Wed May 17, 2006 3:29 pm
by Christopher
Ambush Commander wrote:I want to draw attention to the very first architectural decision we will have to make for this system: where to store the answer to "Is this user authenticated?" The first implementation relied on the calling code to pass around return value of the function, which was extremely cumbersome, as it would end up being passed through many layers without actually being used.
Well it is a start to know the question: "Is this user authenticated?", of course the following question is: "for what?" so we will need to deal with the details of that at some point.
Ambush Commander wrote:The registry is supposed to be the "correct" way to globalize values, but these two lines were incredibly cumbersome and unpopular (they also appeared all over the application).
Unfortunately we will quickly unravel here because it is going to become very implementation specific. Two thoughts: First is that just because it is
"cumbersome and unpopular" does not mean it is not right ... so we will have to decide that. And we may need several way to get to that object in the end to provide some flexiblty in the implementation. Second, this is what Dependency Injection is for, because it gets rid of one or both of those lines.
Ambush Commander wrote:Furthermore, the SESSION object stored a lot more information then it really needed (to be honest, it basically was the permissions manager).
So it sounds like there needs to be some way to limit the information stored in the persistent data.
Ambush Commander wrote:There really isn't any catch-all way to do this, so I propose that the actual propagation of who the user is and whether or not they are authenticated be offered either optionally or not at all.
I suggested above that there could be several ways to "propogate" that object, you now add "not at all" ... ok.
Ambush Commander wrote:Now, personally, I'd like to see a sample implementation to base my system on, because the question is two fold: 1. where is it stored (globals? singleton? bubbling?) and 2. how much information should accompany the barebones user_id that identify the user?
1. Can you define "sample implementation" or show a rough example.
2. We may not even need "the barebones user_id". Perhaps the flag that said authenticated yes/no, or some other role/group/permission values could be stored separately from user info. Then you could have an user info-less option.

Posted: Wed May 17, 2006 3:56 pm
by Ambush Commander
Well it is a start to know the question: "Is this user authenticated?", of course the following question is: "for what?" so we will need to deal with the details of that at some point.
Not yet though. On the most basic level, all we need to know is whether or not the user is who he says he is. We don't actually have to use the information (even though that would be pretty useless), but by divorcing this from "for what", we can increase flexibility by having a good interface between the two.
I suggested above that there could be several ways to "propogate" that object, you now add "not at all" ... ok.
The main thing is to make sure that, without too much overhead, the ultimate decision on how to propogate is left to the user. It's probably a very good idea to have implementations that should be considered maintained fixtures and not just "samples."
Can you define "sample implementation" or show a rough example.
Sure. (by the way, this uses PHP5's model to make things clearer, but we probably want to make it work for PHP4 to)

Code: Select all

<?php

interface PropagateAuthInterface
{
    public function propagate($user_id);
}

class PropagateAuthWithGlobals implements PropagateAuthInterface
{
    public function propogate($user_id) {
        $_GLOBALS['auth_user_id'] = $user_id;
    }
}

?>
Trivially simple, but affords great flexibility. I hope.
We may not even need "the barebones user_id". Perhaps the flag that said authenticated yes/no, or some other role/group/permission values could be stored separately from user info. Then you could have an user info-less option.
But if we want to display who is logged in... we need user info. Although I agree that authorization probably should be seperated.

Maybe authentication (user password, last log in, etc.) should be stored seperately too?
So it sounds like there needs to be some way to limit the information stored in the persistent data.
Correct. Another method would be to serialize a "User" domain object into the session, but that could quickly get out of sync. On the other hand, you want the name of the user to be on hand so you can paint it on the screen with minimal expense.
Unfortunately we will quickly unravel here because it is going to become very implementation specific. Two thoughts: First is that just because it is
"cumbersome and unpopular" does not mean it is not right ... so we will have to decide that. And we may need several way to get to that object in the end to provide some flexiblty in the implementation. Second, this is what Dependency Injection is for, because it gets rid of one or both of those lines.
Ah, dependency injection. You mean...

Code: Select all

class Object
{
  function getDependency() {
    //grab registry and return dependency?
  }
}
That would be an interesting way of handling the problem, but the next step, put it in a supertype, and then the domain object itself is sort of like a registry. Hrmm...

I'm throwing all these ideas out to you guys. I'm not really discriminating. Too much.

Edit - after further thought, I surely must be mad. This is probably why I didn't want to implement one by myself.

Posted: Wed May 17, 2006 7:14 pm
by alex.barylski
I'm interested in what you guys comes up with...

Waiting patiently

Posted: Wed May 17, 2006 8:32 pm
by alex.barylski
Everah wrote:OK, I had to get in on this thread...

I have never used a PEAR library. I toyed, once, with phplib (templates), but ditched the idea about five seconds after I looked over the code.

I have reused snippets of code from other open source/free-ware apps at various times, but for the most part I code my own app components. I like having the control to make my components do what is necessary, and only what is necessary, for the app. I also like making my code very modular, something that all developers do not always attempt to do. But that is just me.

I kinda like the idea of a code-by-group thing. I might want to get in on something like that if it ever materializes.
Your not alone brother...I much prefer modularity...as I hate source files which are over 500 lines...

Especially in PHP I force myself to go as modular as possible...

Cheers :)

Posted: Wed May 17, 2006 8:35 pm
by Ambush Commander
You know, Hockey, just because you're not on the committee doesn't mean that you can't give input.

Posted: Wed May 17, 2006 8:43 pm
by alex.barylski
Ambush Commander wrote:You know, Hockey, just because you're not on the committee doesn't mean that you can't give input.
I thought about it...

But I've almost completed mine...and I'm curious what a totally different mindset will come up with...not that anyone would listen to my suggestions...but still... :P

So far...from what I can tell...I think were on pretty different paths...options are never a bad thing :)

Tis why I was offering my encouragement as opposed to opinion... :)

Cheers :)

Posted: Wed May 17, 2006 9:02 pm
by Ambush Commander
Code will appear some time. I plan on writing the thing in pencil first.