Difference between revisions of "API/Protect"

From aMember Pro Documentation
Jump to: navigation, search
Line 9: Line 9:
  
  
There is a simple example based on  
+
There is a simple example based on SMF plugin:
 
<source>
 
<source>
 
// file am/application/default/plugins/protect/smf.php
 
// file am/application/default/plugins/protect/smf.php

Revision as of 14:54, 28 June 2011

aMember Pro provides almost zero-programming integration API to interface with third-party scripts.

Without single-login, you have to define only 3 variables and 3 functions:

  - $guessTablePattern and $guessTableFields - 3rd party script users table name without prefix, and some fields from it
  - $groupMode - can be GROUP_NONE for no user groups (user can be just enabled/disabled), GROUP_SINGLE if customer is assigned to 1 usergroup only, and GROUP_MULTI if user can be assigned to multiple user groups in the same time 
  - createTable() : set relations better customer table in 3rd party script and aMember
  - getPasswordFormat() : a constant from SavedPass class or an unique string for new password format
  - getAvailableUserGroups() : return groups list from 3rd party script (required if $groupMode is not GROUP_NONE_


There is a simple example based on SMF plugin:

// file am/application/default/plugins/protect/smf.php
class Am_Protect_Smf extends Am_Protect_Databased
{
    const PLUGIN_DATE = '$Date$';
    const PLUGIN_REVISION = '$Revision$';
 
    const SMF = 'smf';
    // table name without prefix that exists in target database
    protected $guessTablePattern = "members";
    // several fields from the table
    protected $guessFieldsPattern = array(
        'ID_MEMBER', 'memberName',
    );
    protected $groupMode = self::GROUP_SINGLE;
 
    public function afterAddConfigItems(Am_Form_Setup_ProtectDatabased $form)
    {
        parent::afterAddConfigItems($form);
        $form->addText('protect.smf.cookie')->setLabel('SMF Cookie Name');
    }
    // this function is only necessary if software uses its own password format
    // that is not already defined in SavedPass class. If it is exists, you
    // can just return a constant SavedPass::XXXFORMAT and do not implement
    // cryptPassword function below
    // aMember stores passwords in PHPass format (the same as Wordpress) 
    public function getPasswordFormat()
    {
        return self::SMF;
    }
    // this function is only necessary if not-standard format used
    public function cryptPassword($pass, &$salt = null, User $user = null)
    {
        $salt = substr(md5(mt_rand()), 0, 4);
        return sha1(strtolower($user->login) . htmlspecialchars(stripslashes($pass)));
    }
    // return third-party script user record
    // of logged-in customer (that is logged-in to 3rd party script) 
    public function getLoggedInRecord()
    {
        if (!$this->getConfig('cookie')) return;
        $cookie = @$_COOKIE [ $this->getConfig('cookie') ];
        if (!$cookie) return;
        $vars = unserialize($cookie);
        if (!$vars[0]) return;
        $user_id = (int)$vars[0];
        $pwd       = $vars[1];
        if (!$user_id || !$pwd) return;
        $record = $this->getTable()->load($user_id, false);
        if (!$record->isLoaded()) return;
        if ($pwd != sha1($record->passwd . $record->passwordSalt)) return;
        return $record;
    }
    // login customer into third-party script
    public function loginUser(Am_Record $record)
    {
        if (!$this->getConfig('cookie')) return;
        $data = array(
            $record->ID_MEMBER,
            sha1($record->passwd . $record->passwordSalt),
            time() + 3600, // expires
            0, // cookie state
        );
        Am_Controller::setCookie($this->getConfig('cookie'), serialize($data));
 
        // update user record
        $ip   = $_SERVER['REMOTE_ADDR'];
        $ip2 = $_SERVER['REMOTE_ADDR'];
        $record->updateQuick(array(
            'lastLogin' => time(),
            'memberIP'  => "'$ip'",
            'memberIP2' => "'$ip2'",
        ));
        // delete guest session
        $this->getDb()->query("DELETE FROM ?_log_online
            WHERE session = ? 
            LIMIT 1",
            'ip' . $_SERVER['REMOTE_ADDR']);
    }
    // logout customer from third-party script
    public function logoutUser(User $user)
    {
        if (!$this->getConfig('cookie')) return;
        Am_Controller::setCookie($this->getConfig('cookie'), "", time() - 36000);
    }
    // MOST IMPORTANT! 
    // define relation between aMember Pro user fields and the third-party users table
    public function createTable()
    {
        $table = new Am_Protect_Table($this, $this->getDb(), '?_user', 'ID_MEMBER');
        $table->setFieldsMapping(array(
            array(Am_Protect_Table::FIELD_LOGIN, 'memberName'),
            array(Am_Protect_Table::FIELD_LOGIN, 'realName'),
            array(Am_Protect_Table::FIELD_PASS, 'passwd' ),
            array(Am_Protect_Table::FIELD_SALT, 'passwordSalt'),
            array(Am_Protect_Table::FIELD_GROUP_ID, 'ID_GROUP'),
            array(Am_Protect_Table::FIELD_ADDED_STAMP, 'dateRegistered'),
            array(Am_Protect_Table::FIELD_EMAIL, 'emailAddress'),
            array(Am_Protect_Table::FIELD_REMOTE_ADDR, 'memberIP'),
            array(Am_Protect_Table::FIELD_REMOTE_ADDR, 'memberIP2'),
        ));
        return $table;
    }
    // return user groups defined in 3rd party script
    public function getAvailableUserGroups($onlyNormal = false)
    {
        $ret = array();
        foreach ($this->getDb()->select("SELECT
            ID_GROUP as id,
            groupName as title,
            NULL as is_banned,
            (ID_GROUP IN (1,2,3)) as is_admin
            FROM ?_membergroups") as $r)
        {
            $g = new Am_Protect_Databased_Usergroup($r);
            if ($onlyNormal)
                if ($g->isAdmin() || $g->isBanned())
                    continue;
            $ret[$g->getId()] = $g;
        }
        return $ret;
    }
}