SitePoint Sponsor

User Tag List

Page 7 of 11 FirstFirst ... 34567891011 LastLast
Results 151 to 175 of 267
  1. #151
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The reason why I believe there is a many-to-many relationship between Roles and Permissions is because of the following:

    1. One Role could have many permissions (EditReport, DeleteReport, etc.). True.
    2. One Permission (e.g. EditReport) could have (or be associated with) many Roles (e.g. SalesPerson, SalesManager, etc.). True.

    Since both of the statements *seem* to be true, at least in my opinion, I think you *need* a many-to-many relationship. So what is the consequence of *not* having a many-to-many? Well, perhaps then you will have redudant data. There will be an EditReport permission record for SalesPerson and an EditReport record for SalesManager. I guess this isn't *that* big of deal.

    Thanks,

    JT

  2. #152
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by seratonin
    The reason why I believe there is a many-to-many relationship between Roles and Permissions is because of the following:

    1. One Role could have many permissions (EditReport, DeleteReport, etc.). True.
    2. One Permission (e.g. EditReport) could have (or be associated with) many Roles (e.g. SalesPerson, SalesManager, etc.). True.

    Since both of the statements *seem* to be true, at least in my opinion, I think you *need* a many-to-many relationship. So what is the consequence of *not* having a many-to-many? Well, perhaps then you will have redudant data. There will be an EditReport permission record for SalesPerson and an EditReport record for SalesManager. I guess this isn't *that* big of deal.

    Thanks,

    JT
    You're right in the sense that that's the correct answer from the relational database normalization point of view, it is a many to many relationship.

    This is a different paradigm. Let me explain. Forget storage for a moment and concentrate on the domain model (as you yourself suggested). The object graph can have unidirectional or bidirectional relationships. If you want to cover all possibilities, you want both ways: you want a reference from the role to the permission, obviously. You also want a back reference.

    But do we actually need it? Eric Evans tells us that if the application doesn't demand this bidirectional relationship, it's better to keep it unidirectional.

    Quote Originally Posted by Eric Evans
    This refinement actually reflects insight into the domain, as well as making a more practical design. It captures the understanding that one direction of the association is much more meaningful than the other.
    The next question is how to map this to storage. It's actually fairly obvious that you can keep the database design you already have, using association tables. Just do an Association Table Mapping and skip everything that's used to establish the back references. Same thing, only easier and simpler.

    The other possibility would be to try to simplify the database design, too. What I think you could do is embed the entire set of permissions for a role in a column of the role table and get rid of the perm_assign table. You could use whichever way you please of storing a list in a column. This would be a form of the Embedded Value pattern.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  3. #153
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by seratonin
    1. One Role could have many permissions (EditReport, DeleteReport, etc.). True.
    Agree.

    Quote Originally Posted by seratonin
    2. One Permission (e.g. EditReport) could have (or be associated with) many Roles (e.g. SalesPerson, SalesManager, etc.). True.
    Disagree.

    Actually I am happy to cave in on this for now . I think it will sort itself out later one way or the other.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  4. #154
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by dagfinn
    Now let me object to myself: what about different kinds of storage? Once you start storing the data in different ways, wouldn't you need some kind of storage abstraction that could be used by both?
    This was what I ended up trying to do . The communication problem, between the authorisation and the administration caused me headaches. They needed to be able to find the same storage mechanism to be in sync. The solution, an options class (sort of Registry) got too complicated for the size of the problem. This is a "Container" style solution where the components know globally how to find resources.

    Beware accidental containers ! Simply using one object as a factory for the other, and bridging the storage, made things much simpler.

    Quote Originally Posted by dagfinn
    One possibility if we really are aiming for something "storage independent" is what Kent Beck calls Triangulation: we choose two different storage methods and drive the design from those. The more different the two are, the more general and abstract the design is likely be.
    Agree totally. How's about we all have another crack at that spec? Either test cases or use cases (select to taste). We went a lot fatser when we had concrete code. Heck, we even got the tests passing .

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  5. #155
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dagfinn
    You're right in the sense that that's the correct answer from the relational database normalization point of view, it is a many to many relationship.

    This is a different paradigm. Let me explain. Forget storage for a moment and concentrate on the domain model (as you yourself suggested). The object graph can have unidirectional or bidirectional relationships. If you want to cover all possibilities, you want both ways: you want a reference from the role to the permission, obviously. You also want a back reference.

    But do we actually need it? Eric Evans tells us that if the application doesn't demand this bidirectional relationship, it's better to keep it unidirectional.


    The next question is how to map this to storage. It's actually fairly obvious that you can keep the database design you already have, using association tables. Just do an Association Table Mapping and skip everything that's used to establish the back references. Same thing, only easier and simpler.

    The other possibility would be to try to simplify the database design, too. What I think you could do is embed the entire set of permissions for a role in a column of the role table and get rid of the perm_assign table. You could use whichever way you please of storing a list in a column. This would be a form of the Embedded Value pattern.
    Alright, I'm with ya. We can keep the data model with a many-to-many in order to avoid rundundant storage, but in the object model we will have a one-to-many. Can we weed out duplicates in the Mapper classes? dagfinn, how would you change the proposed domain model to accommodate this?

    JT

  6. #156
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by seratonin
    Alright, I'm with ya. We can keep the data model with a many-to-many in order to avoid rundundant storage, but in the object model we will have a one-to-many. Can we weed out duplicates in the Mapper classes? dagfinn, how would you change the proposed domain model to accommodate this?
    JT
    Well, I relalize I haven't thought this through yet. I'm learning something. What I'm asking myself is what kind of object a permission is. Is it a value object or a reference object? (I'm using Fowler's naming; Evans talks about value objects and entities.) In fact, is there a pressing reason why a permission should be represented as an object at all?

    Does the list of permissions need to be stored in the database? There may be something I've missed, but from what I've seen so far in this thread , permission 'do_stuff' has no real meaning unless it's named expicitly in code to choose a path of action depending on the current user's authorization. So why would you need to create a new permission except when you're adding new authorization code? If you have to change code anyway, perhaps the entire set of permissions might as well be hard coded? So taking the the setUp test code we might change this:

    PHP Code:
    $edit->addPermission('do_stuff');
    $edit->permit('pleb''do_stuff'); 
    To this:

    PHP Code:
    $edit->permit('pleb'PERM_DO_STUFF); 
    Or, using methods as "class constants" in PHP 4;
    PHP Code:
    $edit->permit('pleb'Permission::DO_STUFF());

    //  Permission class:
    class Permission {
        function 
    DO_STUFF { return 0; }
        function 
    DO_OTHER_STUFF { return 1; }
        
    // etc. 
    The database schema could be the same, only with the permissions table removed.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  7. #157
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by dagfinn
    What I'm asking myself is what kind of object a permission is. Is it a value object or a reference object?
    It will depend on context . At the point of authorisation, it will be read only. When under administration either a reference (incremental updates) or value prior to a transactional update.

    Still trying to focus on requirements...

    Some possible scenarios:
    1) Central authorisation server (PHP may not be used by the client).
    2) Distributed application (what happens when it is upgraded).
    3) Multiple PHP apps using the same data store.
    4) Single app being upgraded (need new permissions added to roles as a batch job).

    I would avoid serialised PHP objects if possible (except when caching) if there are other options that are just as easy.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  8. #158
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Disagree.


    You are not alone in this respect Marcus - I also believe that a Permission should only be assigned to one Role, whereas a Role can have as many Permissions as required

  9. #159
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    It will depend on context . At the point of authorisation, it will be read only. When under administration either a reference (incremental updates) or value prior to a transactional update.
    I was focusing on the context we've established so far, and concluding that it was a value object or even just a value.

    I don't see what difference incremental vs. transactional update makes. Could you explain?
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  10. #160
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dagfinn
    Well, I relalize I haven't thought this through yet. I'm learning something. What I'm asking myself is what kind of object a permission is. Is it a value object or a reference object? (I'm using Fowler's naming; Evans talks about value objects and entities.) In fact, is there a pressing reason why a permission should be represented as an object at all?

    Does the list of permissions need to be stored in the database? There may be something I've missed, but from what I've seen so far in this thread , permission 'do_stuff' has no real meaning unless it's named expicitly in code to choose a path of action depending on the current user's authorization. So why would you need to create a new permission except when you're adding new authorization code? If you have to change code anyway, perhaps the entire set of permissions might as well be hard coded? So taking the the setUp test code we might change this:

    PHP Code:
    $edit->addPermission('do_stuff');
    $edit->permit('pleb''do_stuff'); 
    To this:

    PHP Code:
    $edit->permit('pleb'PERM_DO_STUFF); 
    Or, using methods as "class constants" in PHP 4;
    PHP Code:
    $edit->permit('pleb'Permission::DO_STUFF());

    //  Permission class:
    class Permission {
        function 
    DO_STUFF { return 0; }
        function 
    DO_OTHER_STUFF { return 1; }
        
    // etc. 
    The database schema could be the same, only with the permissions table removed.
    If you store the permissions in the database you can dynamically assign them to specific roles without changing code.

    JT

  11. #161
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by dagfinn
    I don't see what difference incremental vs. transactional update makes. Could you explain?
    Now I think about it, it sounds a bit iffy .

    If you have a transaction (not the invisible DB kind) you save the whole lot as a lump. The objects to be dispatched can be played with as much as you want because they don't have any persisent meaning yet. When you save some of them out (at the end of a script say) you assign a bundle of unique ones to the DB and out they go. The identity is only important at the point of dispatch.

    With an incrementally writing script, the object has to be kept in sync with the DB throughout the script and so assumes the identity. The same if calculations are being done on the basis of the object.

    This is one of my half thought out things .

    I also think permission/operation is a value. Changing one for a role is the same as dropping that permission from the role and then adding the correct one. A sure sign that it is a value; for an entity you would have to rename it directly.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  12. #162
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by seratonin
    If you store the permissions in the database you can dynamically assign them to specific roles without changing code.
    You can anyway. It's easy to get confused, but that is what my altered example does.
    PHP Code:
    $edit->permit('pleb'PERM_DO_STUFF); 
    "pleb" is a role. We're assigning the "do stuff" permission to it by executing code, not changing code.

    You could build a user interface on top of this, showing all the roles taken from the database and the hard-coded permissions, letting you mix and match them as you please.

    What you can't do without changing code is to add a completely new permission to the list of allowed permissions.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  13. #163
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi.

    If no one posts new test cases or use cases within the next few posts, I'll have another go.

    Be afraid...

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  14. #164
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Hi.

    If no one posts new test cases or use cases within the next few posts, I'll have another go.

    Be afraid...

    yours, Marcus
    I think the original idea of simply returning a permission set is where we should more forward. I propose the following:

    PHP Code:
    $authenticator =& new Authenticator($connection);
    if (
    $userId $authenticator->authenticate($username$password)) {
        
    $authorizer =& new Authorizer($connection);
        
    $permissions =& $authorizer->getPermissions($userId);

        if (
    $permissions->hasPermission("editReport")) {

        }

    With this in mind, I will scrape some try to scrape some test cases together.

    Thanks,

    JT

  15. #165
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, I used sike's UMI reflector and posiden to model my solution to the problem. It was interesting. Please, comment and critic.

    PHP Code:
     <?php
    class Security implements IAuthentication{
    static function 
    getPrinciple(){
    return 
    Authentication::getPrinciple();
    }
     
    static function 
    isLoggedIn(){
    return 
    Authentication::isLoggedIn();
    }
     
    static function 
    logOut(){
    return 
    Authentication::logOut();
    }
     
    static function 
    logIn(){
    return 
    Authentication::logIn();
    }
     
    static private function 
    getAuthenticationGatewayConfig(){
    return 
    "mysql";
    }
     
    static function 
    newPermission($admin FALSE){
    $gateWay self::getAuthenticationGatewayConfig()."AuthorizationGateway";
    $gateWay .= ($admin) ? "Admin" "User";
    return new 
    $gateWay();
    }
    }
    interface 
    IAuthentication{
    static function 
    getPrinciple();
    static function 
    isLoggedIn();
    static function 
    logOut();
    static function 
    logIn();
    }
     
    //Since Authorization is the focus this is left as a dummy implementation although it COULD be set up 
    //as a factory for one or more Authentications
    class Authentication implements IAuthentication{
    static private 
    $principle '12345';
    static private 
    $loginStatus FALSE;
     
    static function 
    getPrinciple(){
    return 
    self::$principle;
    }
     
    static function 
    isLoggedIn(){
    return 
    self::$loginStatus;
    }
     
    static function 
    logOut(){
    self::$loginStatus FALSE;
    }
     
    static function 
    logIn(){
    self::$loginStatus TRUE;
    }
     
    }
     
    abstract class 
    Authorization{
    protected 
    $principle NULL;
    protected 
    $permission NULL;
    static private 
    $gateway;
     
    final function 
    __construct(){
    $this -> principle Authentication::getPrinciple();
    }
     
    final function 
    setPerm($permission){
    $this -> permission $permission;
    }
     
    final function 
    getPerm(){
    return 
    $this -> permission;
    }
    }
     
    interface 
    IAuthorizationGatewayUser{
    function 
    check();
    }
    class 
    mysqlAuthorizationGatewayUser extends Authorization implements IAuthorizationGatewayUser
    {
    function 
    check(){
    //Check mysql way (Database query)
    if ($this -> principle == Security::getPrinciple() && Security::isLoggedIn())
    return 
    TRUE;
    else
    return 
    FALSE;
    }
    }
    interface 
    IAuthorizationGatewayAdmin{
    function 
    addRole();
    function 
    deleteRole();
    function 
    addPermission();
    function 
    deletePermission();
    }
    class 
    mysqlAuthorizationGatewayAdmin extends mysqlAuthorizationGatewayUser implements IAuthorizationGatewayAdmin
    {
    function 
    addRole($role){}
    function 
    deleteRole($role){}
    function 
    addPermission($permission){}
    function 
    deletePermission($permission){}
    }
    Security::logIn();
    echo 
    "Principle: ".Security::getPrinciple()." Loggon Status: ".Security::isLoggedIn();
    echo 
    "<BR>";
    if (
    Security::isLoggedIn()){
    $permission Security::newPermission(TRUE);
    $permission -> setPerm('canSpeak');
    //Security::logOut(); // Makes the permission fail
     
    if ($permission -> check()){
    echo 
    "Permission: <b>".$permission -> getPerm()."</b> has <B>PASSED</B>!";
    }
    else
    echo 
    "Permission: <b>".$permission -> getPerm()."</b> has <B>FAILED</B>!";
    }
    else
    echo 
    "<BR>Not even Logged in you clod!";
    ?>
    Re: Edit: reloaded PDF

    PS: I'm not sure if my UML diagram is labeled correctly could someone help? Also, I used a gateway and a factory as requested by the initial post but as a caveeat I included a Security class that covers all the implementation. the security class could also also a Authentication factory so that more than one Authentication can be used.

    I went for flexability and power on this solve. This was a new experiance and even though I somewhat jumped the gun on the tutorial. I hope others can post solves so we can discuss and learn.
    Attached Files Attached Files
    Last edited by Resolution; Apr 27, 2004 at 13:28.

  16. #166
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it is looking pretty good. I will inspect it more closely when I get home from work. What about making Authorization an interface and having Security implement both IAuthentication and IAuthorization?

    BTW, what is "sike's UMI reflector class"?

    JT

  17. #167
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    BTW, what is "sike's UMI reflector class"?
    I'm refering to this thread.

    What about making Authorization an interface and having Security implement both IAuthentication and IAuthorization?
    I decided to remove IAuthorization and simply make Authentication an abstract class, which keeps the implementation lighter class wise yet maintains a correct structure no matter how it's initiated.

    So by using the factory and gateway combo on Authorization allows for all the design criteria to be met - I believe. Oh yea.. I "think" I'm using a gateway pattern but I'm going to recheck to be certain that the interfaces and classes are properly labeled.

    I'm really not sure about the UML diagram - being I'm new to the exercise - so if anyone who has UML class model skills wants to point out something I'd appreciate it.
    Last edited by Resolution; Apr 27, 2004 at 21:42.

  18. #168
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I got rid of the magic function in Security and added a bit more class documentation.

    PHP Code:
    <?php
    class Security implements IAuthentication{
    static function 
    getPrinciple(){
    return 
    Authentication::getPrinciple();
    }
     
    static function 
    isLoggedIn(){
    return 
    Authentication::isLoggedIn();
    }
     
    static function 
    logOut(){
    return 
    Authentication::logOut();
    }
     
    static function 
    logIn(){
    return 
    Authentication::logIn();
    }
     
    static private function 
    getAuthenticationGatewayConfig(){
    return 
    "mysql";
    }
     
    static function 
    newAdminPermission(){
    $gateWay self::getAuthenticationGatewayConfig()."AuthorizationGatewayAdmin";
    return new 
    $gateWay();
    }
     
    static function 
    newUserPermission(){
    $gateWay self::getAuthenticationGatewayConfig()."AuthorizationGatewayUser";
    return new 
    $gateWay();
    }
    }
    interface 
    IAuthentication{
    static function 
    getPrinciple();
    static function 
    isLoggedIn();
    static function 
    logOut();
    static function 
    logIn();
    }
     
    class 
    Authentication implements IAuthentication{
    static private 
    $principle '12345';
    static private 
    $loginStatus FALSE;
     
    static function 
    getPrinciple(){
    return 
    self::$principle;
    }
     
    static function 
    isLoggedIn(){
    return 
    self::$loginStatus;
    }
     
    static function 
    logOut(){
    self::$loginStatus FALSE;
    }
     
    static function 
    logIn(){
    self::$loginStatus TRUE;
    }
     
    }
     
     
    abstract class 
    Authorization{
    protected 
    $principle NULL;
    protected 
    $permission NULL;
    static private 
    $gateway;
     
    final function 
    __construct(){
    $this -> principle Authentication::getPrinciple();
    }
     
    final function 
    setPerm($permission){
    $this -> permission $permission;
    }
     
    final function 
    getPerm(){
    return 
    $this -> permission;
    }
    }
     
     
    interface 
    IAuthorizationGatewayUser{
    function 
    check();
    }
     
    class 
    mysqlAuthorizationGatewayUser extends Authorization implements IAuthorizationGatewayUser
    {
    function 
    check(){
    //Check mysql way (Database query)
    if ($this -> principle == Security::getPrinciple() && Security::isLoggedIn())
    return 
    TRUE;
    else
    return 
    FALSE;
    }
    }
     
    interface 
    IAuthorizationGatewayAdmin{
    function 
    addRole();
    function 
    deleteRole();
    function 
    addPermission();
    function 
    deletePermission();
    }
     
    class 
    mysqlAuthorizationGatewayAdmin extends mysqlAuthorizationGatewayUser implements IAuthorizationGatewayAdmin
    {
    function 
    addRole($role){}
    function 
    deleteRole($role){}
    function 
    addPermission($permission){}
    function 
    deletePermission($permission){}
    }
     
    Security::logIn();
    echo 
    "Principle: ".Security::getPrinciple()." Loggon Status: ".Security::isLoggedIn();
    echo 
    "<BR>";
     
    if (
    Security::isLoggedIn()){
    $permission Security::newUserPermission(); //Initiates a simple/light User permission 
    //object with limited functionality
     
    #$permission = Security::newAdminPermission(); //Initiates a complex/heavy Admin permission 
    //object with maximum functionality
     
    $permission -> setPerm('canSpeak');
    //Security::logOut(); // Makes the permission fail
     
    if ($permission -> check()){
    echo 
    "Permission: <b>".$permission -> getPerm()."</b> has <B>PASSED</B>!";
    }
    else
    echo 
    "Permission: <b>".$permission -> getPerm()."</b> has <B>FAILED</B>!";
    }
    else
    echo 
    "<BR>Not even Logged in you clod!";
     
    ?>
    I added somthing outside of the design criteria but seems like a good idea.

    If the client is logged out after a permission has been initiated it automaticlly fails as well. Ie, permission will not be granted unless one is Authenticated as well. Seems like a sound idea, but it wasn't required in the schema.
    Last edited by Resolution; Apr 27, 2004 at 21:41.

  19. #169
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Resolution
    I got rid of the magic function in Security and added a bit more class documentation.

    PHP Code:
    <?php
    class Security implements IAuthentication{
    static function 
    getPrinciple(){
    return 
    Authentication::getPrinciple();
    }
     
    static function 
    isLoggedIn(){
    return 
    Authentication::isLoggedIn();
    }
     
    static function 
    logOut(){
    return 
    Authentication::logOut();
    }
     
    static function 
    logIn(){
    return 
    Authentication::logIn();
    }
     
    static private function 
    getAuthenticationGatewayConfig(){
    return 
    "mysql";
    }
     
    static function 
    newAdminPermission(){
    $gateWay self::getAuthenticationGatewayConfig()."AuthorizationGatewayAdmin";
    return new 
    $gateWay();
    }
     
    static function 
    newUserPermission(){
    $gateWay self::getAuthenticationGatewayConfig()."AuthorizationGatewayUser";
    return new 
    $gateWay();
    }
    }
    interface 
    IAuthentication{
    static function 
    getPrinciple();
    static function 
    isLoggedIn();
    static function 
    logOut();
    static function 
    logIn();
    }
     
    class 
    Authentication implements IAuthentication{
    static private 
    $principle '12345';
    static private 
    $loginStatus FALSE;
     
    static function 
    getPrinciple(){
    return 
    self::$principle;
    }
     
    static function 
    isLoggedIn(){
    return 
    self::$loginStatus;
    }
     
    static function 
    logOut(){
    self::$loginStatus FALSE;
    }
     
    static function 
    logIn(){
    self::$loginStatus TRUE;
    }
     
    }
     
     
    abstract class 
    Authorization{
    protected 
    $principle NULL;
    protected 
    $permission NULL;
    static private 
    $gateway;
     
    final function 
    __construct(){
    $this -> principle Authentication::getPrinciple();
    }
     
    final function 
    setPerm($permission){
    $this -> permission $permission;
    }
     
    final function 
    getPerm(){
    return 
    $this -> permission;
    }
    }
     
     
    interface 
    IAuthorizationGatewayUser{
    function 
    check();
    }
     
    class 
    mysqlAuthorizationGatewayUser extends Authorization implements IAuthorizationGatewayUser
    {
    function 
    check(){
    //Check mysql way (Database query)
    if ($this -> principle == Security::getPrinciple() && Security::isLoggedIn())
    return 
    TRUE;
    else
    return 
    FALSE;
    }
    }
     
    interface 
    IAuthorizationGatewayAdmin{
    function 
    addRole();
    function 
    deleteRole();
    function 
    addPermission();
    function 
    deletePermission();
    }
     
    class 
    mysqlAuthorizationGatewayAdmin extends mysqlAuthorizationGatewayUser implements IAuthorizationGatewayAdmin
    {
    function 
    addRole($role){}
    function 
    deleteRole($role){}
    function 
    addPermission($permission){}
    function 
    deletePermission($permission){}
    }
     
    Security::logIn();
    echo 
    "Principle: ".Security::getPrinciple()." Loggon Status: ".Security::isLoggedIn();
    echo 
    "<BR>";
     
    if (
    Security::isLoggedIn()){
    $permission Security::newUserPermission(); //Initiates a simple/light User permission 
    //object with limited functionality
     
    #$permission = Security::newAdminPermission(); //Initiates a complex/heavy Admin permission 
    //object with maximum functionality
     
    $permission -> setPerm('canSpeak');
    //Security::logOut(); // Makes the permission fail
     
    if ($permission -> check()){
    echo 
    "Permission: <b>".$permission -> getPerm()."</b> has <B>PASSED</B>!";
    }
    else
    echo 
    "Permission: <b>".$permission -> getPerm()."</b> has <B>FAILED</B>!";
    }
    else
    echo 
    "<BR>Not even Logged in you clod!";
     
    ?>
    I added somthing outside of the design criteria but seems like a good idea.

    If the client is logged out after a permission has been initiated it automaticlly fails as well. Ie, permission will not be granted unless one is Authenticated as well. Seems like a sound idea, but it wasn't required in the schema.
    I definitely like where you are going with this. How 'bout simplifying and compining the AuthorizationGatewayUser and AuthorizationGatewayAdmin and then putting together some SimpleTest test cases?

    JT

  20. #170
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ** Bump **

  21. #171
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Widow Maker
    ** Bump **
    Although, this topic has sparked some great discussion, I think fundamentally the reason why it hasn't continued of late is because there were several different designs proposed and no real concensus. How can we reach some sort of compromise so that we can actually implement something and learn from it?

    JT

  22. #172
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The original problem was the task was too complex and designing the solution was going to be a problem anyways because of it.

    If this could be simplified or toned down, then there would be less room for disagreements No one could argue about simplicity as I see it

    The topic to begin this thread was ideal, though taken way over the top in the sense of a standard which very few people would actually need to implement in their day to day working life.

    I think this point has been brought up ?

  23. #173
    Ceci n'est pas Zoef Zoef's Avatar
    Join Date
    Nov 2002
    Location
    Malta
    Posts
    1,111
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Or maybe it is because it failed to live up to its title?

    "Patterns Tutorial Series"?

    Better title might be... "Discussion on making a simple problem complex beyond the understanding of 99% of the php community by some gurus that can't agree on anything."

    I'd actually be really interested in a "Patterns Tutorial Series", but this isn't it.

    Rik
    English tea - Italian coffee - Maltese wine - Belgian beer - French Cognac

  24. #174
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by seratonin
    Although, this topic has sparked some great discussion, I think fundamentally the reason why it hasn't continued of late is because there were several different designs proposed and no real concensus.
    I have only recently got back from holiday and have been looking to forward to reviving this thread. Random comments since my last post...

    I think building the Security class was a good idea even though it isn't within the requirements. It has forced us to think about the interfaces again.

    I think the way forward though is either sample client code or test cases. I am not sure how the UML code clarified anything. UML is great stuff when requirements are clear, but it is really easy to create castles in the air.

    I am happy with either PHP5 or PHP4, but it is harder for me to run PHP5 stuff.

    What is wrong with this test case...?
    PHP Code:
    class RoleBasedPermissionsTest extends UnitTestCase 
        function 
    RoleBasedPermissionsTest() { 
            
    $this->UnitTestCase();
        } 
        function 
    setUp() { 
            
    $authoriser = &new Authoriser();
            
    $authoriser->addPrincipal('fred'); 
            
    $authoriser->assign('fred''pleb'); 
            
    $authoriser->permit('pleb''do_stuff');
        } 
        function 
    tearDown() { 
            
    $authoriser = &new Authoriser();
            
    $authoriser->dropPrincipal('fred'); 
            
    $authoriser->dropRole('pleb'); 
        } 
        function 
    testNonUserHasNothingAllowed() {
            
    $authoriser = &new Authoriser();
            
    $permissions = &$authoriser->getPermissions('nobody');
            
    $this->assertFalse($permissions->can('do_stuff')); 
        } 
        function 
    testLegitimateUserHasActionAllowed() { 
            
    $authoriser = &new Authoriser();
            
    $permissions = &$authoriser->getPermissions('fred'); 
            
    $this->assertTrue($permissions->can('do_stuff')); 
        } 
        function 
    testUserCannotDoNonAction() { 
            
    $authoriser = &new Authoriser();
            
    $permissions = &$authoriser->getPermissions('fred'); 
            
    $this->assertFalse($permissions->can('do_unknown')); 
        } 

    I have removed the storage flexibility for now (it can be put in later if needed) and assumed that the editing methods will fill out needed data automatically. This is the simplest starting point I can come up with.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  25. #175
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Hi...



    I have only recently got back from holiday and have been looking to forward to reviving this thread. Random comments since my last post...

    I think building the Security class was a good idea even though it isn't within the requirements. It has forced us to think about the interfaces again.

    I think the way forward though is either sample client code or test cases. I am not sure how the UML code clarified anything. UML is great stuff when requirements are clear, but it is really easy to create castles in the air.

    I am happy with either PHP5 or PHP4, but it is harder for me to run PHP5 stuff.

    What is wrong with this test case...?
    PHP Code:
    class RoleBasedPermissionsTest extends UnitTestCase 
        function 
    RoleBasedPermissionsTest() { 
            
    $this->UnitTestCase();
        } 
        function 
    setUp() { 
            
    $authoriser = &new Authoriser();
            
    $authoriser->addPrincipal('fred'); 
            
    $authoriser->assign('fred''pleb'); 
            
    $authoriser->permit('pleb''do_stuff');
        } 
        function 
    tearDown() { 
            
    $authoriser = &new Authoriser();
            
    $authoriser->dropPrincipal('fred'); 
            
    $authoriser->dropRole('pleb'); 
        } 
        function 
    testNonUserHasNothingAllowed() {
            
    $authoriser = &new Authoriser();
            
    $permissions = &$authoriser->getPermissions('nobody');
            
    $this->assertFalse($permissions->can('do_stuff')); 
        } 
        function 
    testLegitimateUserHasActionAllowed() { 
            
    $authoriser = &new Authoriser();
            
    $permissions = &$authoriser->getPermissions('fred'); 
            
    $this->assertTrue($permissions->can('do_stuff')); 
        } 
        function 
    testUserCannotDoNonAction() { 
            
    $authoriser = &new Authoriser();
            
    $permissions = &$authoriser->getPermissions('fred'); 
            
    $this->assertFalse($permissions->can('do_unknown')); 
        } 

    I have removed the storage flexibility for now (it can be put in later if needed) and assumed that the editing methods will fill out needed data automatically. This is the simplest starting point I can come up with.

    yours, Marcus
    I agree that this test case is simple. What about other developers? Can we move forward with this test case as the base for our design/implementation?

    JT


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •