Difference between revisions of "API/Protect"

From aMember Pro Documentation
Jump to: navigation, search
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
aMember Pro provides almost zero-programming integration API to interface with third-party scripts.
 
aMember Pro provides almost zero-programming integration API to interface with third-party scripts.
 +
 +
  Note: try to use http://yoursite.com/amember/admin-plugin-maker. It is a great tool that will make an
 +
  integration plugin template for you.
  
 
Without single-login, you have to define only 3 variables and 3 functions:
 
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
+
* $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  
+
* $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
+
* createTable() : set relations between customer table fields in 3rd party script, and aMember fields
  - getPasswordFormat() : a constant from SavedPass class or an unique string for new password format
+
* 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_
+
* getAvailableUserGroups() : return groups list from 3rd party script (required if $groupMode is not GROUP_NONE)
  
  
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
 
class Am_Protect_Smf extends Am_Protect_Databased
 
class Am_Protect_Smf extends Am_Protect_Databased
 
{
 
{
     const PLUGIN_DATE = '$Date$';
+
     const PLUGIN_STATUS = self::STATUS_DEV;
     const PLUGIN_REVISION = '$Revision$';
+
     const PLUGIN_REVISION = '@@VERSION@@';
  
 
     const SMF = 'smf';
 
     const SMF = 'smf';
    // table name without prefix that exists in target database
+
 
 
     protected $guessTablePattern = "members";
 
     protected $guessTablePattern = "members";
    // several fields from the table
 
 
     protected $guessFieldsPattern = array(
 
     protected $guessFieldsPattern = array(
 
         'ID_MEMBER', 'memberName',
 
         'ID_MEMBER', 'memberName',
Line 29: Line 31:
 
     {
 
     {
 
         parent::afterAddConfigItems($form);
 
         parent::afterAddConfigItems($form);
 +
        // @todo eliminate necessarity of prefix here!
 
         $form->addText('protect.smf.cookie')->setLabel('SMF Cookie Name');
 
         $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()
 
     public function getPasswordFormat()
 
     {
 
     {
 
         return self::SMF;
 
         return self::SMF;
 
     }
 
     }
    // this function is only necessary if not-standard format used
+
 
 
     public function cryptPassword($pass, &$salt = null, User $user = null)
 
     public function cryptPassword($pass, &$salt = null, User $user = null)
 
     {
 
     {
 
         $salt = substr(md5(mt_rand()), 0, 4);
 
         $salt = substr(md5(mt_rand()), 0, 4);
         return sha1(strtolower($user->login) . htmlspecialchars(stripslashes($pass)));
+
         return sha1(strtolower($user->login) . $this->un_htmlspecialchars(stripslashes($pass)));
 
     }
 
     }
    // return third-party script user record
+
 
     // of logged-in customer (that is logged-in to 3rd party script)  
+
     /// what the shit is it for in password hashing? who knows...
 +
    function un_htmlspecialchars($string)
 +
    {
 +
        return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES)) + array('&#039;' => '\'', '&nbsp;' => ' '));
 +
    }
 +
 
 
     public function getLoggedInRecord()
 
     public function getLoggedInRecord()
 
     {
 
     {
Line 63: Line 66:
 
         return $record;
 
         return $record;
 
     }
 
     }
    // login customer into third-party script
+
 
     public function loginUser(Am_Record $record)
+
     public function loginUser(Am_Record $record, $password)
 
     {
 
     {
 
         if (!$this->getConfig('cookie')) return;
 
         if (!$this->getConfig('cookie')) return;
Line 89: Line 92:
 
             'ip' . $_SERVER['REMOTE_ADDR']);
 
             'ip' . $_SERVER['REMOTE_ADDR']);
 
     }
 
     }
    // logout customer from third-party script
 
 
     public function logoutUser(User $user)
 
     public function logoutUser(User $user)
 
     {
 
     {
Line 95: Line 97:
 
         Am_Controller::setCookie($this->getConfig('cookie'), "", time() - 36000);
 
         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()
 
     public function createTable()
 
     {
 
     {
         $table = new Am_Protect_Table($this, $this->getDb(), '?_user', 'ID_MEMBER');
+
         $table = new Am_Protect_Table($this, $this->getDb(), '?_members', 'ID_MEMBER');
 
         $table->setFieldsMapping(array(
 
         $table->setFieldsMapping(array(
 
             array(Am_Protect_Table::FIELD_LOGIN, 'memberName'),
 
             array(Am_Protect_Table::FIELD_LOGIN, 'memberName'),
Line 113: Line 114:
 
         return $table;
 
         return $table;
 
     }
 
     }
    // return user groups defined in 3rd party script
+
     public function getAvailableUserGroupsSql()
     public function getAvailableUserGroups($onlyNormal = false)
+
 
     {
 
     {
         $ret = array();
+
         return "SELECT
        foreach ($this->getDb()->select("SELECT
+
 
             ID_GROUP as id,
 
             ID_GROUP as id,
 
             groupName as title,
 
             groupName as title,
 
             NULL as is_banned,
 
             NULL as is_banned,
 
             (ID_GROUP IN (1,2,3)) as is_admin
 
             (ID_GROUP IN (1,2,3)) as is_admin
             FROM ?_membergroups") as $r)
+
             FROM ?_membergroups";
        {
+
            $g = new Am_Protect_Databased_Usergroup($r);
+
            if ($onlyNormal)
+
                if ($g->isAdmin() || $g->isBanned())
+
                    continue;
+
            $ret[$g->getId()] = $g;
+
        }
+
        return $ret;
+
 
     }
 
     }
 
}
 
}
 
</source>
 
</source>

Latest revision as of 03:19, 27 November 2012

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

 Note: try to use http://yoursite.com/amember/admin-plugin-maker. It is a great tool that will make an
 integration plugin template for you.

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 between customer table fields in 3rd party script, and aMember fields
  • 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_STATUS = self::STATUS_DEV;
    const PLUGIN_REVISION = '@@VERSION@@';
 
    const SMF = 'smf';
 
    protected $guessTablePattern = "members";
    protected $guessFieldsPattern = array(
        'ID_MEMBER', 'memberName',
    );
    protected $groupMode = self::GROUP_SINGLE;
 
    public function afterAddConfigItems(Am_Form_Setup_ProtectDatabased $form)
    {
        parent::afterAddConfigItems($form);
        // @todo eliminate necessarity of prefix here!
        $form->addText('protect.smf.cookie')->setLabel('SMF Cookie Name');
    }
    public function getPasswordFormat()
    {
        return self::SMF;
    }
 
    public function cryptPassword($pass, &$salt = null, User $user = null)
    {
        $salt = substr(md5(mt_rand()), 0, 4);
        return sha1(strtolower($user->login) . $this->un_htmlspecialchars(stripslashes($pass)));
    }
 
    /// what the shit is it for in password hashing? who knows...
    function un_htmlspecialchars($string)
    {
        return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES)) + array('&#039;' => '\'', '&nbsp;' => ' '));
    }
 
    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;
    }
 
    public function loginUser(Am_Record $record, $password)
    {
        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']);
    }
    public function logoutUser(User $user)
    {
        if (!$this->getConfig('cookie')) return;
        Am_Controller::setCookie($this->getConfig('cookie'), "", time() - 36000);
    }
 
    public function createTable()
    {
        $table = new Am_Protect_Table($this, $this->getDb(), '?_members', '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;
    }
    public function getAvailableUserGroupsSql()
    {
        return "SELECT
            ID_GROUP as id,
            groupName as title,
            NULL as is_banned,
            (ID_GROUP IN (1,2,3)) as is_admin
            FROM ?_membergroups";
    }
}