Welcome Guest, Not a member yet? Register   Sign In
MeNeedz Auth

[eluser]meteor[/eluser]
Thx for reply Wink)
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. Wink))

Thx for your reply

regards

[eluser]meteor[/eluser]
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 Wink))

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

///////////////////////////////////////////////////////////////// Myauth.php
Code:
<?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;
    }
  }
?>

[eluser]meteor[/eluser]
and some tests
/////////////////////////////////////// MyauthTest.php

Code:
<?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()
    {
    }
}    
?>

[eluser]charlie spider[/eluser]
@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

[eluser]davidbehler[/eluser]
Actually there IS such an option Smile
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
Code:
$this->auth->has_access('group_name');

[eluser]charlie spider[/eluser]
wow thanks for the fast reply.

i mean is there a way to add the user group when using the
Code:
$this->auth->register();
function ?


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

Code:
echo form_open('welcome/register');
    $data = array(
                  'name'        => 'user_name',
                  'id'          => 'user_name',
                  'maxlength'   => '50',
                  'size'        => '50'
                );
    echo "name: ".form_input($data);
?>
<br/>
&lt;?
    $data = array(
                  'name'        => 'user_password',
                  'id'          => 'user_password',
                  'maxlength'   => '50',
                  'size'        => '50'
                );
    echo "pass: ".form_password($data);
?&gt;
<br/>
&lt;?
    $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

[eluser]davidbehler[/eluser]
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?

[eluser]charlie spider[/eluser]
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.

[eluser]charlie spider[/eluser]
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.

[eluser]davidbehler[/eluser]
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.




Theme © iAndrew 2016 - Forum software by © MyBB