ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

MeNeedz Auth

November 09, 2008 6:23pm

Subscribe [31]
  • #166 / Jul 17, 2009 2:14pm

    Mat-Moo

    350 posts

    You understand wrong then, although the function does check that the data is not blank. I would not classify this as validation. Although you must remember that with XSS turned on the post data has already been “Cleaned” etc.

    Edit: I understand what you are saying, but why would you do validation at that point? Validation would have to be done before performing any action (e.g. Register) in which case you have already validated the form data before hand.

  • #167 / Jul 17, 2009 2:32pm

    meteor

    31 posts

    Well, in my opinion checking if something is false (no data) or ‘’ (empty) is validating ... and it means that we are validating twice here ... Have a look how long that if condition is ... It’s slows things down and repeats operation which should have already been done ... just to return false… in my opinion this fragment of code should be refactored. This function is supposed to return true (in case of successful registration) or false ... so it should be given 100 % valid data. If data is not valid it should not be run. What’s more it would be good to delegate optional object to this function to save data with ... If something went wrong with saving ... Array of errors would be returned ... otherwise true ...

    Just my humble opinion ... 😉))

  • #168 / Jul 17, 2009 2:38pm

    Mat-Moo

    350 posts

    Better safe than sorry imo.

  • #169 / Jul 17, 2009 2:44pm

    meteor

    31 posts

    right, but running overlapping code twice is inefficient ... Single check is enough in this case ..

    regards

  • #170 / Jul 17, 2009 6:42pm

    davidbehler

    708 posts

    I finally had time to look into the library again and you are right, there is no real validation done except checking for FALSE/empty value. But as I’m passing the second parameter as TRUE to the $this->input->post() method, the data is run through the XSS filter.

    I guess it’s totally save to drop the check for empty value and only check for FALSE. But I doubt that you will really feel a difference compared to checking for FALSE and empty value instead of only FALSE.

    As far as error message instead of FALSE as return values are concerned I didn’t implement those as that would require internationlization and would make the library further complicated. If you really want me to, I will add the feature in form of an additional language file ‘auth_lang.php’ or something similar.

  • #171 / Jul 17, 2009 7:57pm

    meteor

    31 posts

    Thx for reply 😉)
    I have another question, basically i’m not taking advantage of DataMapper for my current project, just plain sql as some queries would use too much memory. I think there is no way to return an sql error code( in case valid data has not been saved to the database by register() ). In my opinion, it would be quite easy to fix this. You would only have to add an extra property for the main object to store the last sql error in case such has occured ...

    As to checking for false values and filtering ... I think this functionality should be delegated to another function in the worst case ... Register() is monumental at the moment, the fewer conditions you store in it the better in my opinion. One function should be responsible for one thing. it would be even better to assume that data passed to this function is clean already (say, you pass array with input data, which was already cleaned and validated externaly, this way you give developers possibility to choose their tools ... You know, validation is one thing, but you still have to deal with rendering errors.). It has yet another advantage, register() is shorter and easier to test and debug. Finally, I believe that validation has nothing to do with registration,and as such should not be mixed in to Auth class. As I mentioned, register function should just get data and save it to the database, return result of the operation and make sure that eventual sql error is available for developers to retrieve ... Decoupling validation and registration would solve the problem of error messages too. Form_validation class would take care of all the stuff related to checking if input was valid.

    Of course these are just my loose thoughts that come into my mind when I look at your code ... You should not feel yourself obliged to adding any further functionality, even thought you are the author of Auth class, You have done a lot already. 😉)) 

    Thx for your reply

    regards

  • #172 / Jul 18, 2009 3:08pm

    meteor

    31 posts

    Just wrote a small class for auth purposes ...
    It actually does two things:
    1. encrypts password with sha1 or md5 hashing function and adds salt component in turn writing all that to the database
    2. it authenticates user with data fetched from database ...

    There is no data validation. It assumes that it has already been done and input is clean ...
    It does not write anything to the database itself ... al this is delegated to your model object.
    Both authenticate and register funcs get model object as their second argument.
    This class is supposed to be instantiated in your controller and after prior checking of all your input data(there is no need to instantiate it if input data is dirty anyway).

    It assumes, you have at least one model which coresponds to your database table
    the table itself should have user,password(40 or 32),salt(9) and email(optional) fields

    This is just simple example, written and tested in my spare time (today) ... and as such should be treated ...
    I hope you(david) find it useful 😉))

    I’m attaching a few tests below the class ... regards

    ///////////////////////////////////////////////////////////////// Myauth.php

    <?php // if ( ! defined('BASEPATH')) exit('No direct script access allowed');
      class MyAuth{
        var $config = null;
        var $defaults = array(
          // we use sha1 for creating hashes
          'hash' => 'sha1',
          // salt_lenght should be 9 characters(ASCII assumed)
          'salt_length' => 9,
        ); 
        function __construct($config = array()){
         // use md5, but nothing else, if you does not like sha1 ...
          if(isset($config['hash']) and !in_array($config['hash'],array('sha1','md5'))){ throw new Exception('Hash type not supproted'); }
          $this->config = array_merge($this -> defaults,$config);
        }
        // this function just gets CLEAN data, creates hashed, salted password
        // and delegates writing data to the user_model
        // $data should look like this: 
        // $data = array('user' => 'my_user', 'password' => 'her_password','email' => '[email protected]');
        // $user_model is an instance of user_model
        function register($data,$user_model){
          $this->_salt($data['password']);
          $data['password'] = $this->salted_password; 
          $data['salt'] = $this->salt;
          return $user_model -> put_user($data); 
        }
        // this is an authentication function
        // it gets CLEAN data in the form of: array('user' => 'my_user', 'password' => 'her_password');  
        // and compares it with data fetched from database
        // the second argment to this func is a model object
        // (say, user) which is responsible for fetching data from db 
        function authenticate($data,$user_model){
          $db_data = $user_model -> get_user($data['user']);
          if(empty($db_data)){ return false; }   
          $user_obj = $db_data[0];
          $e_password = $user_obj -> password;  
          $this -> _salt($data['password'],$user_obj -> salt);
          return $this -> salted_password == $user_obj ->  password  ? true : false;     
        }
        // this should be made private !!!
        // it does not return anything ...
        // salted password is stored in $this -> salted_password;
        // salt used to reinforce password is stored in $this -> salt property  
        function _salt($password,$e_salt = null){
          $salt = is_null($e_salt) ? substr(uniqid(rand(),true),0,$this->config['salt_length']) : $e_salt;
          $this -> salted_password = $this -> config['hash'] == 'sha1' ? sha1($salt.$password) : md5($salt.$password);
          $this -> salt =  $salt;
        }
      }
    ?>
  • #173 / Jul 18, 2009 3:09pm

    meteor

    31 posts

    and some tests
    ///////////////////////////////////////  MyauthTest.php

    <?php
    include_once('./../Myauth.php');
    
    class Usermodel{ 
      function __construct(){
      }
      function get_user($user_name){ 
        return array(
           (object)array(
               'salt' => '113190741',
               'user_name' => 'my_user',
               'password' => '80c6d23a925e760ef3b38fdb43e003c0ae99ab3f'
           ) 
        );
      }
      function put_user($data){
        return true;
      }
    }
    
    class MyauthTest extends PHPUnit_Framework_TestCase {
            protected function setUp()
        {
          // auth object
          $this->al = new Myauth();
        }
        public function test_config()
        { 
           $this->assertEquals(2,count($this->al->config));
           $this->assertEquals('sha1',$this->al->config['hash']);
        }
        public function test__salt(){
           $password = 'her_password';
           // sha1 check
           $this->al->_salt($password);
           // this should be 40 characters long
           $s_password = $this->al->salted_password;
           // this should be 9 characters long
           $salt = $this->al->salt;
           
           $this->assertEquals(40,strlen($this->al->salted_password ) );
           $this->assertEquals(9,strlen($this->al->salt) );
           // comparing passwords 
           $this->al->_salt($password,$salt);
           // ensure that converted salt and password components match converted value
           $this->assertEquals($s_password,$this->al->salted_password); 
           
           // make sure that _salt returns different results even when hash is based on the sam password 
           $this->al->_salt($password);
           $salted_pass_1 = $this->al->salted_password;
           $this->al->_salt($password);
           $salted_pass_2 = $this->al->salted_password;
           $this->assertNotEquals($salted_pass_1,$salted_pass_2);
           
           // md5 works the same way but returns string made up of 32 bites;
        }
        //make sure register works as expected
        function test_register(){
          $data = array('user' => 'my_user', 'password' => 'her_password','email' => '[email protected]');
          $user_model = new Usermodel;    
          $this->assertTrue($this->al->register($data, $user_model));
        } 
        function test_authenticate(){
          $user_model = new Usermodel();
          // auth data
          $data = array('user' => 'my_user', 'password' => 'her_password');
          $this -> assertTrue($this->al->authenticate($data,$user_model));
        } 
        protected function tearDown()
        {
        }
    }    
    ?>
  • #174 / Jul 21, 2009 5:21am

    charlie spider

    125 posts

    @meteor
    please start a new thread if you want to post your own creations


    Hey David,

    it’s late here in BC and i’m staring at your excellent Auth library trying to figure out if there is a built in way to set the group level when registering a new user.

    i don’t think there is, but i’m also so tired that i keep thinking i have spiders crawling on me (and i’m 100% sober), so i may be looking right at it and not seeing it.

    i have a cms for a large website that will have multiple levels of access for both the frontend and the admin side of the site. Four levels for the frontend ( guest, member, moderator and super mod ) plus three levels for the admin section ( author, admin and super admin ). i will need to set the auth level when registering each user.

    also went to check out your DBlog, looks pretty promising but haven’t really had a chance to do anything with it. keep up the good work.


    thanks for all of your help

  • #175 / Jul 21, 2009 5:50am

    davidbehler

    708 posts

    Actually there IS such an option 😊
    You can either save the user group within your user table or, if a user can be member of multiple groups, save it in an additional table.

    Have a look at the guide, the second to last section “How to configure user groups” should be what you need.

    You can even use my library to determine wether as user is member of a given group or not and therefor restrict his access or not using

    $this->auth->has_access('group_name');
  • #176 / Jul 21, 2009 6:15am

    charlie spider

    125 posts

    wow thanks for the fast reply.

    i mean is there a way to add the user group when using the

    $this->auth->register();

    function ?


    for example, i have added a user groups select box to basically the same thing you have in your guide:

    echo form_open('welcome/register');
        $data = array(
                      'name'        => 'user_name',
                      'id'          => 'user_name',
                      'maxlength'   => '50',
                      'size'        => '50'
                    );
        echo "name: ".form_input($data);
    ?>
    <br>
    <?
        $data = array(
                      'name'        => 'user_password',
                      'id'          => 'user_password',
                      'maxlength'   => '50',
                      'size'        => '50'
                    );
        echo "pass: ".form_password($data);
    ?>
    <br>
    <?
        $data = array(
                      'name'        => 'user_email',
                      'id'          => 'user_email',
                      'maxlength'   => '50',
                      'size'        => '50'
                    );
        echo "email: ".form_input($data);
    
        echo heading('Administrative Level', 6);
        echo form_dropdown('admin_level' , $auth_levels, $this->input->post('admin_level') );
    
    
        echo form_hidden('user_id', 123345);
        echo form_submit('mysubmit', 'Submit Post!');
        echo form_close();

    how will your register function handle this ??

    thanks again

  • #177 / Jul 21, 2009 6:23am

    davidbehler

    708 posts

    It won’t xD

    Right now it does not support setting the user group according to an input field. You can rather set a standard user group for all new users in the config.

    Why would you have that drop down in the registration form anyway? Can a user decide himself what user groups he wants to be in?

  • #178 / Jul 21, 2009 6:31am

    charlie spider

    125 posts

    no it’s for a user management section in the admin side of the site.

    the site admins choose the access levels for users they create

    like i said above, there are four levels for the frontend of the site ( guest, member, moderator and super mod ) plus three levels for the admin section ( author, admin and super admin ).

    The “member” access group is the only one that would require automatic setting, but even so it is still dependant on the admins accepting an application. All of the other levels will be created at the discretion of the site admins.

  • #179 / Jul 21, 2009 6:34am

    charlie spider

    125 posts

    but i have an upcoming project where users will in a sense be deciding their level of access based on paid membership. would be nice if upon a successfull transaction you can then set their group level during registration.

  • #180 / Jul 21, 2009 6:40am

    davidbehler

    708 posts

    So your users can’t register themself but rather ask to be registered by an admin?
    I see why manually selecting the user group by the admin might make sense here.

    As I said before, that’s currently not supported but it shouldn’t be too much of a problem to add that feature.
    I will look into this later.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases