]> gitweb.fluxo.info Git - semanticscuttle.git/commitdiff
move ssl client cert handling into separate service class
authorChristian Weiske <cweiske@cweiske.de>
Mon, 9 May 2011 05:52:44 +0000 (07:52 +0200)
committerChristian Weiske <cweiske@cweiske.de>
Mon, 9 May 2011 05:52:44 +0000 (07:52 +0200)
src/SemanticScuttle/Service/User.php
src/SemanticScuttle/Service/User/SslClientCert.php [new file with mode: 0644]

index bf7c61d7949097ad64ec2a602b2f4793d9113b7a..4af8e14498ef304fc3f068137846ac53a461402a 100644 (file)
@@ -167,15 +167,30 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
         return $password;
     }
 
-    function _updateuser($uId, $fieldname, $value) {
+    /**
+     * Updates a single field in the user's database row
+     *
+     * @param integer $uId       ID of the user
+     * @param string  $fieldname Name of table column to change
+     * @param string  $value     New value
+     *
+     * @return boolean True if all was well, false if not
+     */
+    public function _updateuser($uId, $fieldname, $value)
+    {
         $updates = array ($fieldname => $value);
-        $sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
+        $sql = 'UPDATE '. $this->getTableName()
+            . ' SET '. $this->db->sql_build_array('UPDATE', $updates)
+            . ' WHERE '. $this->getFieldName('primary') . '=' . intval($uId);
 
         // Execute the statement.
         $this->db->sql_transaction('begin');
-        if (!($dbresult = $this->db->sql_query($sql))) {
+        if (!($dbresult = $this->db->sql_query($sql))) {
             $this->db->sql_transaction('rollback');
-            message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
+            message_die(
+                GENERAL_ERROR, 'Could not update user', '',
+                __LINE__, __FILE__, $sql, $this->db
+            );
             return false;
         }
         $this->db->sql_transaction('commit');
@@ -390,10 +405,11 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
                 $this->db->sql_freeresult($dbresult);
                 return (int)$_SESSION[$this->getSessionKey()];
             }
-        } else if (isset($_SERVER['SSL_CLIENT_M_SERIAL'])
-            && isset($_SERVER['SSL_CLIENT_V_END'])
-        ) {
-            $id = $this->getUserIdFromSslClientCert();
+        }
+
+        $ssls = SemanticScuttle_Service_Factory::get('User_SslClientCert');
+        if ($ssls->hasValidCert()) {
+            $id = $ssls->getUserIdFromCert();
             if ($id !== false) {
                 $this->setCurrentUserId($id);
                 return (int)$_SESSION[$this->getSessionKey()];
@@ -428,56 +444,6 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
 
 
 
-    /**
-     * Tries to detect the user ID from the SSL client certificate passed
-     * to the web server.
-     *
-     * @return mixed Integer user ID if the certificate is valid and
-     *               assigned to a user, boolean false otherwise
-     */
-    protected function getUserIdFromSslClientCert()
-    {
-        if (!isset($_SERVER['SSL_CLIENT_M_SERIAL'])
-            || !isset($_SERVER['SSL_CLIENT_V_END'])
-            || !isset($_SERVER['SSL_CLIENT_VERIFY'])
-            || $_SERVER['SSL_CLIENT_VERIFY'] !== 'SUCCESS'
-            || !isset($_SERVER['SSL_CLIENT_I_DN'])
-        ) {
-            return false;
-        }
-
-        if ($_SERVER['SSL_CLIENT_V_REMAIN'] <= 0) {
-            return false;
-        }
-
-        $serial         = $_SERVER['SSL_CLIENT_M_SERIAL'];
-        $clientIssuerDn = $_SERVER['SSL_CLIENT_I_DN'];
-
-        $query = 'SELECT uId'
-            . ' FROM ' . $this->getTableName() . '_sslclientcerts'
-            . ' WHERE sslSerial = \'' . $this->db->sql_escape($serial) . '\''
-            . ' AND sslClientIssuerDn = \''
-            . $this->db->sql_escape($clientIssuerDn)
-            . '\'';
-        if (!($dbresult = $this->db->sql_query($query))) {
-            message_die(
-                GENERAL_ERROR, 'Could not load user for client certificate',
-                '', __LINE__, __FILE__, $query, $this->db
-            );
-            return false;
-        }
-
-        $row = $this->db->sql_fetchrow($dbresult);
-        $this->db->sql_freeresult($dbresult);
-
-        if (!$row) {
-            return false;
-        }
-        return (int)$row['uId'];
-    }
-
-
-
     /**
      * Try to authenticate and login a user with
      * username and password.
@@ -670,23 +636,57 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
         return $uId;
     }
 
-    function updateUser($uId, $password, $name, $email, $homepage, $uContent) {
-        if (!is_numeric($uId))
-        return false;
+    /**
+     * Updates the given user
+     *
+     * @param integer $uId      ID of user to change
+     * @param string  $password Password to use
+     * @param string  $name     Realname to use
+     * @param string  $email    Email to use
+     * @param string  $homepage User's homepage
+     * @param string  $uContent User note
+     *
+     * @return boolean True when all is well, false if not
+     */
+    public function updateUser(
+        $uId, $password, $name, $email, $homepage, $uContent
+    ) {
+        if (!is_numeric($uId)) {
+            return false;
+        }
 
         // Set up the SQL UPDATE statement.
         $moddatetime = gmdate('Y-m-d H:i:s', time());
-        if ($password == '')
-        $updates = array ('uModified' => $moddatetime, 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
-        else
-        $updates = array ('uModified' => $moddatetime, 'password' => $this->sanitisePassword($password), 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
-        $sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
+        if ($password == '') {
+            $updates = array(
+                'uModified' => $moddatetime,
+                'name'      => $name,
+                'email'     => $email,
+                'homepage'  => $homepage,
+                'uContent'  => $uContent
+            );
+        } else {
+            $updates = array(
+                'uModified' => $moddatetime,
+                'password'  => $this->sanitisePassword($password),
+                'name'      => $name,
+                'email'     => $email,
+                'homepage'  => $homepage,
+                'uContent'  => $uContent
+            );
+        }
+        $sql = 'UPDATE '. $this->getTableName()
+            . ' SET '. $this->db->sql_build_array('UPDATE', $updates)
+            . ' WHERE '. $this->getFieldName('primary') . '=' . intval($uId);
 
         // Execute the statement.
         $this->db->sql_transaction('begin');
         if (!($dbresult = & $this->db->sql_query($sql))) {
             $this->db->sql_transaction('rollback');
-            message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
+            message_die(
+                GENERAL_ERROR, 'Could not update user', '',
+                __LINE__, __FILE__, $sql, $this->db
+            );
             return false;
         }
         $this->db->sql_transaction('commit');
@@ -695,6 +695,8 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
         return true;
     }
 
+
+
     function getAllUsers ( ) {
         $query = 'SELECT * FROM '. $this->getTableName();
 
diff --git a/src/SemanticScuttle/Service/User/SslClientCert.php b/src/SemanticScuttle/Service/User/SslClientCert.php
new file mode 100644 (file)
index 0000000..7b0c1eb
--- /dev/null
@@ -0,0 +1,161 @@
+<?php
+/**
+ * SemanticScuttle - your social bookmark manager.
+ *
+ * PHP version 5.
+ *
+ * @category Bookmarking
+ * @package  SemanticScuttle
+ * @author   Christian Weiske <cweiske@cweiske.de>
+ * @license  AGPL http://www.gnu.org/licenses/agpl.html
+ * @link     http://sourceforge.net/projects/semanticscuttle
+ */
+
+/**
+ * SemanticScuttle SSL client certificate management service
+ *
+ * @category Bookmarking
+ * @package  SemanticScuttle
+ * @author   Christian Weiske <cweiske@cweiske.de>
+ * @license  AGPL http://www.gnu.org/licenses/agpl.html
+ * @link     http://sourceforge.net/projects/semanticscuttle
+ */
+class SemanticScuttle_Service_User_SslClientCert extends SemanticScuttle_DbService
+{
+    /**
+     * Creates a new instance, sets database variable and table name.
+     *
+     * @param sql_db $db Database object
+     */
+    protected function __construct($db)
+    {
+        $this->db = $db;
+        $this->tablename  = $GLOBALS['tableprefix'] .'users_sslclientcerts';
+    }
+
+    /**
+     * Returns the single service instance
+     *
+     * @param sql_db $db Database object
+     *
+     * @return SemanticScuttle_Service_User
+     */
+    public static function getInstance($db)
+    {
+        static $instance;
+        if (!isset($instance)) {
+            $instance = new self($db);
+        }
+        return $instance;
+    }
+
+    /**
+     * Determines if the browser provided a valid SSL client certificate
+     *
+     * @return boolean True if the client cert is there and is valid
+     */
+    public function hasValidCert()
+    {
+        if (!isset($_SERVER['SSL_CLIENT_M_SERIAL'])
+            || !isset($_SERVER['SSL_CLIENT_V_END'])
+            || !isset($_SERVER['SSL_CLIENT_VERIFY'])
+            || $_SERVER['SSL_CLIENT_VERIFY'] !== 'SUCCESS'
+            || !isset($_SERVER['SSL_CLIENT_I_DN'])
+        ) {
+            return false;
+        }
+
+        if ($_SERVER['SSL_CLIENT_V_REMAIN'] <= 0) {
+            return false;
+        }
+
+        return true;
+    }
+
+
+
+    /**
+     * Registers the currently available SSL client certificate
+     * with the given user. As a result, the user will be able to login
+     * using the certifiate
+     *
+     * @param integer $uId User ID to attach the client cert to.
+     *
+     * @return boolean True if registration was well, false if not.
+     */
+    public function registerCurrentCertificate($uId)
+    {
+        //FIXME
+    }
+
+
+    /**
+     * Takes values from the currently available SSL client certificate
+     * and adds the available profile data to the user.
+     *
+     * @param integer $uId User ID to attach the client cert to.
+     *
+     * @return array Array of profile data that were registered.
+     *               Database column name as key, new value as value
+     */
+    public function updateProfileFromCurentCert($uId)
+    {
+        $arData = array();
+
+        if (isset($_SERVER['SSL_CLIENT_S_DN_CN'])
+            && trim($_SERVER['SSL_CLIENT_S_DN_CN']) != ''
+        ) {
+            $arData['name'] = trim($_SERVER['SSL_CLIENT_S_DN_CN']);
+        }
+
+        if (count($arData)) {
+            foreach ($arData as $column => $value) {
+                $userservice->_updateuser($uId, $column, $value);
+            }
+        }
+        return $arData;
+    }
+
+
+
+    /**
+     * Tries to detect the user ID from the SSL client certificate passed
+     * to the web server.
+     *
+     * @return mixed Integer user ID if the certificate is valid and
+     *               assigned to a user, boolean false otherwise
+     */
+    public function getUserIdFromCert()
+    {
+        if (!$this->hasValidCert()) {
+            return false;
+        }
+
+        $serial         = $_SERVER['SSL_CLIENT_M_SERIAL'];
+        $clientIssuerDn = $_SERVER['SSL_CLIENT_I_DN'];
+
+        $query = 'SELECT uId'
+            . ' FROM ' . $this->getTableName()
+            . ' WHERE sslSerial = \'' . $this->db->sql_escape($serial) . '\''
+            . ' AND sslClientIssuerDn = \''
+            . $this->db->sql_escape($clientIssuerDn)
+            . '\'';
+        if (!($dbresult = $this->db->sql_query($query))) {
+            message_die(
+                GENERAL_ERROR, 'Could not load user for client certificate',
+                '', __LINE__, __FILE__, $query, $this->db
+            );
+            return false;
+        }
+
+        $row = $this->db->sql_fetchrow($dbresult);
+        $this->db->sql_freeresult($dbresult);
+
+        if (!$row) {
+            return false;
+        }
+        return (int)$row['uId'];
+    }
+
+}
+?>
\ No newline at end of file