]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch '0.9.x' into mapstraction
authorEvan Prodromou <evan@status.net>
Wed, 18 Nov 2009 14:20:31 +0000 (09:20 -0500)
committerEvan Prodromou <evan@status.net>
Wed, 18 Nov 2009 14:20:31 +0000 (09:20 -0500)
README
actions/designadminpanel.php
db/statusnet_pg.sql
lib/form.php
plugins/LdapAuthentication/LdapAuthenticationPlugin.php
plugins/LdapAuthentication/README
plugins/Realtime/realtimeupdate.js
theme/base/css/display.css
theme/default/css/display.css

diff --git a/README b/README
index fb78ab01d2654da423cbcea8cbfe8fa94b3e88ba..eb1fb8cd70a7e3dd28fdbb04a8eeb4939254dba2 100644 (file)
--- a/README
+++ b/README
@@ -852,6 +852,12 @@ locale_path: full path to the directory for locale data. Unless you
             store all your locale data in one place, you probably
             don't need to use this.
 language: default language for your site. Defaults to US English.
+          Note that this is overridden if a user is logged in and has
+          selected a different language. It is also overridden if the
+          user is NOT logged in, but their browser requests a different
+          langauge. Since pretty much everybody's browser requests a
+          language, that means that changing this setting has little or
+          no effect in practice.
 languages: A list of languages supported on your site. Typically you'd
           only change this if you wanted to disable support for one
           or another language:
index dcf5605af17cc2869b0ca2888050e050c399157c..d1aadc8c276ee112a151af5541ab175ca939d405 100644 (file)
@@ -47,6 +47,10 @@ if (!defined('STATUSNET')) {
 
 class DesignadminpanelAction extends AdminPanelAction
 {
+
+    /* The default site design */
+    var $design = null;
+
     /**
      * Returns the page title
      *
@@ -77,6 +81,8 @@ class DesignadminpanelAction extends AdminPanelAction
 
     function showForm()
     {
+        $this->design = Design::siteDesign();
+
         $form = new DesignAdminPanelForm($this);
         $form->show();
         return;
@@ -90,8 +96,44 @@ class DesignadminpanelAction extends AdminPanelAction
 
     function saveSettings()
     {
-        static $settings = array('theme');
+        if ($this->arg('save')) {
+            $this->saveDesignSettings();
+        } else if ($this->arg('defaults')) {
+            $this->restoreDefaults();
+        } else {
+            $this->success = false;
+            $this->message = 'Unexpected form submission.';
+        }
+    }
+
+    /**
+     * Save the new design settings
+     *
+     * @return void
+     */
+
+    function saveDesignSettings()
+    {
+
+        // Workaround for PHP returning empty $_POST and $_FILES when POST
+        // length > post_max_size in php.ini
+
+        if (empty($_FILES)
+            && empty($_POST)
+            && ($_SERVER['CONTENT_LENGTH'] > 0)
+        ) {
+            $msg = _('The server was unable to handle that much POST ' .
+                'data (%s bytes) due to its current configuration.');
+            $this->success = false;
+            $this->msg     = $e->getMessage(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
+            return;
+        }
+
+        // check for an image upload
+
+        $bgimage = $this->saveBackgroundImage();
 
+        static $settings = array('theme');
         $values = array();
 
         foreach ($settings as $setting) {
@@ -99,6 +141,30 @@ class DesignadminpanelAction extends AdminPanelAction
         }
 
         // This throws an exception on validation errors
+        try {
+            $bgcolor = new WebColor($this->trimmed('design_background'));
+            $ccolor  = new WebColor($this->trimmed('design_content'));
+            $sbcolor = new WebColor($this->trimmed('design_sidebar'));
+            $tcolor  = new WebColor($this->trimmed('design_text'));
+            $lcolor  = new WebColor($this->trimmed('design_links'));
+        } catch (WebColorException $e) {
+            $this->success = false;
+            $this->msg = $e->getMessage();
+            return;
+        }
+
+        $onoff = $this->arg('design_background-image_onoff');
+
+        $on   = false;
+        $off  = false;
+
+        if ($onoff == 'on') {
+            $on = true;
+        } else {
+            $off = true;
+        }
+
+        $tile = $this->boolean('design_background-image_repeat');
 
         $this->validate($values);
 
@@ -112,21 +178,163 @@ class DesignadminpanelAction extends AdminPanelAction
             Config::save('site', $setting, $values[$setting]);
         }
 
+        if (isset($bgimage)) {
+            Config::save('design', 'backgroundimage', $bgimage);
+        }
+
+        Config::save('design', 'backgroundcolor', $bgcolor->intValue());
+        Config::save('design', 'contentcolor', $ccolor->intValue());
+        Config::save('design', 'sidebarcolor', $sbcolor->intValue());
+        Config::save('design', 'textcolor', $tcolor->intValue());
+        Config::save('design', 'linkcolor', $lcolor->intValue());
+
+        // Hack to use Design's bit setter
+        $scratch = new Design();
+        $scratch->setDisposition($on, $off, $tile);
+
+        Config::save('design', 'disposition', $scratch->disposition);
+
         $config->query('COMMIT');
 
         return;
+
+    }
+
+    /**
+     * Delete a design setting
+     *
+     * @return mixed $result false if something didn't work
+     */
+
+    function deleteSetting($section, $setting)
+    {
+        $config = new Config();
+
+        $config->section = $section;
+        $config->setting = $setting;
+
+        if ($config->find(true)) {
+            $result = $config->delete();
+            if (!$result) {
+                common_log_db_error($config, 'DELETE', __FILE__);
+                $this->clientError(_("Unable to delete design setting."));
+                return null;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+      * Restore the default design
+      *
+      * @return void
+      */
+
+    function restoreDefaults()
+    {
+        $this->deleteSetting('site', 'theme');
+
+        $settings = array(
+            'theme', 'backgroundimage', 'backgroundcolor', 'contentcolor',
+            'sidebarcolor', 'textcolor', 'linkcolor', 'disposition'
+        );
+
+        foreach ($settings as $setting) {
+            $this->deleteSetting('design', $setting);
+        }
+    }
+
+    /**
+     * Save the background image if the user uploaded one
+     *
+     * @return string $filename the filename of the image
+     */
+
+    function saveBackgroundImage()
+    {
+        $filename = null;
+
+        if ($_FILES['design_background-image_file']['error'] ==
+            UPLOAD_ERR_OK) {
+
+            $filepath = null;
+
+            try {
+                $imagefile =
+                    ImageFile::fromUpload('design_background-image_file');
+            } catch (Exception $e) {
+                $this->success = false;
+                $this->msg     = $e->getMessage();
+                return;
+            }
+
+            // Note: site design background image has a special filename
+
+            $filename = Design::filename('site-design-background',
+                image_type_to_extension($imagefile->type),
+                    common_timestamp());
+
+            $filepath = Design::path($filename);
+
+            move_uploaded_file($imagefile->filepath, $filepath);
+
+            // delete any old backround img laying around
+
+            if (isset($this->design->backgroundimage)) {
+                @unlink(Design::path($design->backgroundimage));
+            }
+
+            return $filename;
+        }
     }
 
+    /**
+     * Attempt to validate setting values
+     *
+     * @return void
+     */
+
     function validate(&$values)
     {
         if (!in_array($values['theme'], Theme::listAvailable())) {
             $this->clientError(sprintf(_("Theme not available: %s"), $values['theme']));
         }
     }
+
+    /**
+     * Add the Farbtastic stylesheet
+     *
+     * @return void
+     */
+
+    function showStylesheets()
+    {
+        parent::showStylesheets();
+        $this->cssLink('css/farbtastic.css','base','screen, projection, tv');
+    }
+
+    /**
+     * Add the Farbtastic scripts
+     *
+     * @return void
+     */
+
+    function showScripts()
+    {
+        parent::showScripts();
+
+        $this->script('js/farbtastic/farbtastic.js');
+        $this->script('js/userdesign.go.js');
+
+        $this->autofocus('design_background-image_file');
+    }
+
 }
 
 class DesignAdminPanelForm extends Form
 {
+
     /**
      * ID of the form
      *
@@ -149,6 +357,22 @@ class DesignAdminPanelForm extends Form
         return 'form_settings';
     }
 
+    /**
+     * HTTP method used to submit the form
+     *
+     * For image data we need to send multipart/form-data
+     * so we set that here too
+     *
+     * @return string the method to use for submitting
+     */
+
+    function method()
+    {
+        $this->enctype = 'multipart/form-data';
+
+        return 'post';
+    }
+
     /**
      * Action of the form
      *
@@ -168,21 +392,179 @@ class DesignAdminPanelForm extends Form
 
     function formData()
     {
+
+        $design = $this->out->design;
+
         $themes = Theme::listAvailable();
 
         asort($themes);
 
         $themes = array_combine($themes, $themes);
 
+        $this->out->elementStart('fieldset', array('id' =>
+            'settings_design_theme'));
+        $this->out->element('legend', null, _('Change theme'));
         $this->out->elementStart('ul', 'form_data');
-        $this->out->elementStart('li');
 
+        $this->out->elementStart('li');
         $this->out->dropdown('theme', _('Theme'),
                              $themes, _('Theme for the site.'),
-                             true, $this->value('theme'));
+                             false, $this->value('theme'));
+        $this->out->elementEnd('li');
+        $this->out->elementEnd('ul');
+        $this->out->elementEnd('fieldset');
 
+
+        $this->out->elementStart('fieldset', array('id' =>
+            'settings_design_background-image'));
+        $this->out->element('legend', null, _('Change background image'));
+        $this->out->elementStart('ul', 'form_data');
+        $this->out->elementStart('li');
+        $this->out->element('label', array('for' => 'design_background-image_file'),
+                                _('Background'));
+        $this->out->element('input', array('name' => 'design_background-image_file',
+                                     'type' => 'file',
+                                     'id' => 'design_background-image_file'));
+        $this->out->element('p', 'form_guide',
+            sprintf(_('You can upload a background image for the site. ' .
+              'The maximum file size is %1$s.'), ImageFile::maxFileSize()));
+        $this->out->element('input', array('name' => 'MAX_FILE_SIZE',
+                                          'type' => 'hidden',
+                                          'id' => 'MAX_FILE_SIZE',
+                                          'value' => ImageFile::maxFileSizeInt()));
         $this->out->elementEnd('li');
+
+        if (!empty($design->backgroundimage)) {
+
+            $this->out->elementStart('li', array('id' =>
+                'design_background-image_onoff'));
+
+            $this->out->element('img', array('src' =>
+                Design::url($design->backgroundimage)));
+
+            $attrs = array('name' => 'design_background-image_onoff',
+                           'type' => 'radio',
+                           'id' => 'design_background-image_on',
+                           'class' => 'radio',
+                           'value' => 'on');
+
+            if ($design->disposition & BACKGROUND_ON) {
+                $attrs['checked'] = 'checked';
+            }
+
+            $this->out->element('input', $attrs);
+
+            $this->out->element('label', array('for' => 'design_background-image_on',
+                                          'class' => 'radio'),
+                                          _('On'));
+
+            $attrs = array('name' => 'design_background-image_onoff',
+                           'type' => 'radio',
+                           'id' => 'design_background-image_off',
+                           'class' => 'radio',
+                           'value' => 'off');
+
+            if ($design->disposition & BACKGROUND_OFF) {
+                $attrs['checked'] = 'checked';
+            }
+
+            $this->out->element('input', $attrs);
+
+            $this->out->element('label', array('for' => 'design_background-image_off',
+                                          'class' => 'radio'),
+                                          _('Off'));
+            $this->out->element('p', 'form_guide', _('Turn background image on or off.'));
+            $this->out->elementEnd('li');
+
+            $this->out->elementStart('li');
+            $this->out->checkbox('design_background-image_repeat',
+                            _('Tile background image'),
+                            ($design->disposition & BACKGROUND_TILE) ? true : false);
+            $this->out->elementEnd('li');
+        }
+
         $this->out->elementEnd('ul');
+        $this->out->elementEnd('fieldset');
+
+        $this->out->elementStart('fieldset', array('id' => 'settings_design_color'));
+        $this->out->element('legend', null, _('Change colours'));
+        $this->out->elementStart('ul', 'form_data');
+
+        try {
+
+            $bgcolor = new WebColor($design->backgroundcolor);
+
+            $this->out->elementStart('li');
+            $this->out->element('label', array('for' => 'swatch-1'), _('Background'));
+            $this->out->element('input', array('name' => 'design_background',
+                                          'type' => 'text',
+                                          'id' => 'swatch-1',
+                                          'class' => 'swatch',
+                                          'maxlength' => '7',
+                                          'size' => '7',
+                                          'value' => ''));
+            $this->out->elementEnd('li');
+
+            $ccolor = new WebColor($design->contentcolor);
+
+            $this->out->elementStart('li');
+            $this->out->element('label', array('for' => 'swatch-2'), _('Content'));
+            $this->out->element('input', array('name' => 'design_content',
+                                          'type' => 'text',
+                                          'id' => 'swatch-2',
+                                          'class' => 'swatch',
+                                          'maxlength' => '7',
+                                          'size' => '7',
+                                          'value' => ''));
+            $this->out->elementEnd('li');
+
+            $sbcolor = new WebColor($design->sidebarcolor);
+
+            $this->out->elementStart('li');
+            $this->out->element('label', array('for' => 'swatch-3'), _('Sidebar'));
+            $this->out->element('input', array('name' => 'design_sidebar',
+                                        'type' => 'text',
+                                        'id' => 'swatch-3',
+                                        'class' => 'swatch',
+                                        'maxlength' => '7',
+                                        'size' => '7',
+                                        'value' => ''));
+            $this->out->elementEnd('li');
+
+            $tcolor = new WebColor($design->textcolor);
+
+            $this->out->elementStart('li');
+            $this->out->element('label', array('for' => 'swatch-4'), _('Text'));
+            $this->out->element('input', array('name' => 'design_text',
+                                        'type' => 'text',
+                                        'id' => 'swatch-4',
+                                        'class' => 'swatch',
+                                        'maxlength' => '7',
+                                        'size' => '7',
+                                        'value' => ''));
+            $this->out->elementEnd('li');
+
+            $lcolor = new WebColor($design->linkcolor);
+
+            $this->out->elementStart('li');
+            $this->out->element('label', array('for' => 'swatch-5'), _('Links'));
+            $this->out->element('input', array('name' => 'design_links',
+                                         'type' => 'text',
+                                         'id' => 'swatch-5',
+                                         'class' => 'swatch',
+                                         'maxlength' => '7',
+                                         'size' => '7',
+                                         'value' => ''));
+            $this->out->elementEnd('li');
+
+        } catch (WebColorException $e) {
+            common_log(LOG_ERR, 'Bad color values in site design: ' .
+                $e->getMessage());
+        }
+
+        $this->out->elementEnd('ul');
+        $this->out->elementEnd('fieldset');
+
     }
 
     /**
@@ -226,6 +608,15 @@ class DesignAdminPanelForm extends Form
 
     function formActions()
     {
-        $this->out->submit('submit', _('Save'), 'submit', null, _('Save site settings'));
-    }
+        $this->out->submit('defaults', _('Use defaults'), 'submit form_action-default',
+                'defaults', _('Restore default designs'));
+
+        $this->out->element('input', array('id' => 'settings_design_reset',
+                                         'type' => 'reset',
+                                         'value' => 'Reset',
+                                         'class' => 'submit form_action-primary',
+                                         'title' => _('Reset back to default')));
+
+        $this->out->submit('save', _('Save'), 'submit form_action-secondary',
+                'save', _('Save design'));    }
 }
index 7b0e5313ceac86560de1953612a772180c7e038a..8dbaf8598142e1715c7ff726db8d809a8a764add 100644 (file)
@@ -571,11 +571,11 @@ create table user_role (
 );
 
 create table login_token (
-    user_id integer not null /* comment 'user owning this token'*/ references user (id),
+    user_id integer not null /* comment 'user owning this token'*/ references "user" (id),
     token char(32) not null /* comment 'token useable for logging in'*/,
     created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created'*/,
     modified timestamp /* comment 'date this record was modified'*/,
 
-    constraint primary key (user_id)
+    primary key (user_id)
 );
 
index 87b7a5cba91c42d0aea1b55ff62eea7a2e1d8712..868c986b93b457097ba29c4316db682d23e9c956 100644 (file)
@@ -67,7 +67,7 @@ class Form extends Widget
     {
         $attributes = array('id' => $this->id(),
             'class' => $this->formClass(),
-            'method' => 'post',
+            'method' => $this->method(),
             'action' => $this->action());
 
         if (!empty($this->enctype)) {
@@ -119,6 +119,18 @@ class Form extends Widget
     {
     }
 
+    /**
+     * HTTP method used to submit the form
+     *
+     * Defaults to post. Subclasses can override if they need to.
+     *
+     * @return string the method to use for submitting
+     */
+     function method()
+     {
+         return 'post';
+     }
+
     /**
      * Buttons for form actions
      *
index 865154730f788c2d460824af56aff9726820c2dc..ad5dd3a02211cb8fcaab64afe2ccc9c73653b1ce 100644 (file)
@@ -46,6 +46,7 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
     public $options=null;
     public $filter=null;
     public $scope=null;
+    public $password_encoding=null;
     public $attributes=array();
 
     function onInitializePlugin(){
@@ -68,10 +69,6 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
 
     function checkPassword($username, $password)
     {
-        $ldap = $this->ldap_get_connection();
-        if(!$ldap){
-            return false;
-        }
         $entry = $this->ldap_get_user($username);
         if(!$entry){
             return false;
@@ -109,8 +106,38 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
 
     function changePassword($username,$oldpassword,$newpassword)
     {
-        //TODO implement this
-        throw new Exception(_('Sorry, changing LDAP passwords is not supported at this time'));
+        if(! isset($this->attributes['password']) || !isset($this->password_encoding)){
+            //throw new Exception(_('Sorry, changing LDAP passwords is not supported at this time'));
+            return false;
+        }
+        $entry = $this->ldap_get_user($username);
+        if(!$entry){
+            return false;
+        }else{
+            $config = $this->ldap_get_config();
+            $config['binddn']=$entry->dn();
+            $config['bindpw']=$oldpassword;
+            if($ldap = $this->ldap_get_connection($config)){
+                $entry = $this->ldap_get_user($username,array(),$ldap);
+                
+                $newCryptedPassword = $this->hashPassword($newpassword, $this->password_encoding);
+                if ($newCryptedPassword===false) {
+                    return false;
+                }
+                if($this->password_encoding=='ad') {
+                    //TODO I believe this code will work once this bug is fixed: http://pear.php.net/bugs/bug.php?id=16796
+                    $oldCryptedPassword = $this->hashPassword($oldpassword, $this->password_encoding);
+                    $entry->delete( array($this->attributes['password'] => $oldCryptedPassword ));
+                }
+                $entry->replace( array($this->attributes['password'] => $newCryptedPassword ), true);
+                if( Net_LDAP2::isError($entry->upate()) ) {
+                    return false;
+                }
+                return true;
+            }else{
+                return false;
+            }
+        }
 
         return false;
     }
@@ -153,8 +180,10 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
      * $param array $attributes LDAP attributes to retrieve
      * @return string DN
      */
-    function ldap_get_user($username,$attributes=array()){
-        $ldap = $this->ldap_get_connection();
+    function ldap_get_user($username,$attributes=array(),$ldap=null){
+        if($ldap==null) {
+            $ldap = $this->ldap_get_connection();
+        }
         $filter = Net_LDAP2_Filter::create($this->attributes['username'], 'equals',  $username);
         $options = array(
             'scope' => 'sub',
@@ -177,4 +206,123 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
             return false;
         }
     }
+    
+    /**
+     * Code originaly from the phpLDAPadmin development team
+     * http://phpldapadmin.sourceforge.net/
+     *
+     * Hashes a password and returns the hash based on the specified enc_type.
+     *
+     * @param string $passwordClear The password to hash in clear text.
+     * @param string $encodageType Standard LDAP encryption type which must be one of
+     *        crypt, ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, or clear.
+     * @return string The hashed password.
+     *
+     */
+
+    function hashPassword( $passwordClear, $encodageType ) 
+    {
+        $encodageType = strtolower( $encodageType );
+        switch( $encodageType ) {
+            case 'crypt': 
+                $cryptedPassword = '{CRYPT}' . crypt($passwordClear,$this->randomSalt(2)); 
+                break;
+                
+            case 'ext_des':
+                // extended des crypt. see OpenBSD crypt man page.
+                if ( ! defined( 'CRYPT_EXT_DES' ) || CRYPT_EXT_DES == 0 ) {return FALSE;} //Your system crypt library does not support extended DES encryption.
+                $cryptedPassword = '{CRYPT}' . crypt( $passwordClear, '_' . $this->randomSalt(8) );
+                break;
+
+            case 'md5crypt':
+                if( ! defined( 'CRYPT_MD5' ) || CRYPT_MD5 == 0 ) {return FALSE;} //Your system crypt library does not support md5crypt encryption.
+                $cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$1$' . $this->randomSalt(9) );
+                break;
+
+            case 'blowfish':
+                if( ! defined( 'CRYPT_BLOWFISH' ) || CRYPT_BLOWFISH == 0 ) {return FALSE;} //Your system crypt library does not support blowfish encryption.
+                $cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$2a$12$' . $this->randomSalt(13) ); // hardcoded to second blowfish version and set number of rounds
+                break;
+
+            case 'md5':
+                $cryptedPassword = '{MD5}' . base64_encode( pack( 'H*' , md5( $passwordClear) ) );
+                break;
+
+            case 'sha':
+                if( function_exists('sha1') ) {
+                    // use php 4.3.0+ sha1 function, if it is available.
+                    $cryptedPassword = '{SHA}' . base64_encode( pack( 'H*' , sha1( $passwordClear) ) );
+                } elseif( function_exists( 'mhash' ) ) {
+                    $cryptedPassword = '{SHA}' . base64_encode( mhash( MHASH_SHA1, $passwordClear) );
+                } else {
+                    return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
+                }
+                break;
+
+            case 'ssha':
+                if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
+                    mt_srand( (double) microtime() * 1000000 );
+                    $salt = mhash_keygen_s2k( MHASH_SHA1, $passwordClear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+                    $cryptedPassword = "{SSHA}".base64_encode( mhash( MHASH_SHA1, $passwordClear.$salt ).$salt );
+                } else {
+                    return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
+                }
+                break;
+
+            case 'smd5':
+                if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
+                    mt_srand( (double) microtime() * 1000000 );
+                    $salt = mhash_keygen_s2k( MHASH_MD5, $passwordClear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+                    $cryptedPassword = "{SMD5}".base64_encode( mhash( MHASH_MD5, $passwordClear.$salt ).$salt );
+                } else {
+                    return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
+                }
+                break;
+
+            case 'ad':
+                $cryptedPassword = '';
+                $passwordClear = "\"" . $passwordClear . "\"";
+                $len = strlen($passwordClear);
+                for ($i = 0; $i < $len; $i++) {
+                    $cryptedPassword .= "{$passwordClear{$i}}\000";
+                }
+
+            case 'clear':
+            default:
+                $cryptedPassword = $passwordClear;
+        }
+
+        return $cryptedPassword;
+    }
+
+    /**
+     * Code originaly from the phpLDAPadmin development team
+     * http://phpldapadmin.sourceforge.net/
+     *
+     * Used to generate a random salt for crypt-style passwords. Salt strings are used
+     * to make pre-built hash cracking dictionaries difficult to use as the hash algorithm uses
+     * not only the user's password but also a randomly generated string. The string is
+     * stored as the first N characters of the hash for reference of hashing algorithms later.
+     *
+     * --- added 20021125 by bayu irawan <bayuir@divnet.telkom.co.id> ---
+     * --- ammended 20030625 by S C Rigler <srigler@houston.rr.com> ---
+     *
+     * @param int $length The length of the salt string to generate.
+     * @return string The generated salt string.
+     */
+     
+    function randomSalt( $length ) 
+    {
+        $possible = '0123456789'.
+            'abcdefghijklmnopqrstuvwxyz'.
+            'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
+            './';
+        $str = "";
+        mt_srand((double)microtime() * 1000000);
+
+        while( strlen( $str ) < $length )
+            $str .= substr( $possible, ( rand() % strlen( $possible ) ), 1 );
+
+        return $str;
+    }
 }
index dc3f4ba884ae8bd1f14e5a99c1b7d9263a9131e1..2226159c2e8a52802e091f786be22f503ffd693f 100644 (file)
@@ -18,6 +18,9 @@ email_changeable (true): Are users allowed to change their email address?
     (true or false)
 password_changeable (true): Are users allowed to change their passwords?
     (true or false)
+password_encoding: required if users are to be able to change their passwords
+    Possible values are: crypt, ext_des, md5crypt, blowfish, md5, sha, ssha,
+        smd5, ad, clear
 
 host*: LDAP server name to connect to. You can provide several hosts in an
     array in which case the hosts are tried from left to right.
@@ -47,6 +50,7 @@ attributes: an array that relates StatusNet user attributes to LDAP ones
     fullname
     homepage
     location
+    password: required if users are to be able to change their passwords
 
 * required
 default values are in (parenthesis)
@@ -67,10 +71,12 @@ addPlugin('ldapAuthentication', array(
     'bindpw'=>'password',
     'basedn'=>'OU=Users,OU=StatusNet,OU=US,DC=americas,DC=global,DC=loc',
     'host'=>array('server1', 'server2'),
+    'password_encoding'=>'ad',
     'attributes'=>array(
         'username'=>'sAMAccountName',
         'nickname'=>'sAMAccountName',
         'email'=>'mail',
-        'fullname'=>'displayName')
+        'fullname'=>'displayName',
+        'password'=>'unicodePwd')
 ));
 
index 9b9991b9ee35704e3e6985e4d74dce130d6b785d..d1cf1d5070792f9d28eb2241b32b142269ccce41 100644 (file)
@@ -34,6 +34,8 @@ RealtimeUpdate = {
      _favorurl: '',
      _deleteurl: '',
      _updatecounter: 0,
+     _maxnotices: 50,
+     _windowhasfocus: true,
 
      init: function(userid, replyurl, favorurl, deleteurl)
      {
@@ -44,13 +46,16 @@ RealtimeUpdate = {
 
         DT = document.title;
 
-        $(window).blur(function() {
+        $(window).bind('focus', function(){ RealtimeUpdate._windowhasfocus = true; });
+
+        $(window).bind('blur', function() {
           $('#notices_primary .notice').removeClass('mark-top');
 
           $('#notices_primary .notice:first').addClass('mark-top');
 
           RealtimeUpdate._updatecounter = 0;
           document.title = DT;
+          RealtimeUpdate._windowhasfocus = false;
 
           return false;
         });
@@ -58,23 +63,32 @@ RealtimeUpdate = {
 
      receive: function(data)
      {
-          setTimeout(function() {
-              id = data.id;
+          id = data.id;
+
+          // Don't add it if it already exists
+          if ($("#notice-"+id).length > 0) {
+               return;
+          }
+
+          var noticeItem = RealtimeUpdate.makeNoticeItem(data);
+          $("#notices_primary .notices").prepend(noticeItem);
+          $("#notices_primary .notice:first").css({display:"none"});
+          $("#notices_primary .notice:first").fadeIn(1000);
 
-              // Don't add it if it already exists
-              if ($("#notice-"+id).length > 0) {
-                   return;
-              }
+          if ($('#notices_primary .notice').length > RealtimeUpdate._maxnotices) {
+               $("#notices_primary .notice:last .form_disfavor").unbind('submit');
+               $("#notices_primary .notice:last .form_favor").unbind('submit');
+               $("#notices_primary .notice:last .notice_reply").unbind('click');
+               $("#notices_primary .notice:last").remove();
+          }
 
-              var noticeItem = RealtimeUpdate.makeNoticeItem(data);
-              $("#notices_primary .notices").prepend(noticeItem);
-              $("#notices_primary .notice:first").css({display:"none"});
-              $("#notices_primary .notice:first").fadeIn(1000);
-              SN.U.NoticeReply();
+          SN.U.NoticeReply();
+          SN.U.NoticeFavor();
 
+          if (RealtimeUpdate._windowhasfocus === false) {
               RealtimeUpdate._updatecounter += 1;
               document.title = '('+RealtimeUpdate._updatecounter+') ' + DT;
-          }, 500);
+          }
      },
 
      makeNoticeItem: function(data)
@@ -178,9 +192,9 @@ RealtimeUpdate = {
          });
          $('#showstream #notices_primary').css({'margin-top':'18px'});
 
-         RT.click(function() {
+         RT.bind('click', function() {
              window.open(url,
-                         timeline,
+                         '',
                          'toolbar=no,resizable=yes,scrollbars=yes,status=yes,width=500,height=550');
 
              return false;
@@ -208,6 +222,12 @@ RealtimeUpdate = {
             'left':'auto',
             'right':'0'
          });
+
+         $('.notices .entry-title a, .notices .entry-content a').bind('click', function() {
+            window.open(this.href, '');
+            
+            return false;
+         });
      }
 }
 
index 96e169d6dc117dda294c36ea5896cd27a0c5d35a..e5f5df68cc1754709bc3d5b799a2f19dc39b3ebb 100644 (file)
@@ -122,8 +122,15 @@ float:left;
 .form_settings .form_data input {
 margin-left:1.795%;
 float:left;
+}
+.form_settings .form_data input {
 width:39%;
 }
+.form_settings .form_data input.submit,
+.form_settings .form_data input.checkbox,
+.form_settings .form_data input.radio {
+width:auto;
+}
 .form_settings .form_data textarea {
 width:63%;
 }
@@ -165,7 +172,8 @@ font-weight:bold;
 #form_password_recover legend,
 #form_password_change legend,
 .form_entity_block legend,
-#form_filter_bytag legend {
+#form_filter_bytag legend,
+#settings_design_theme legend {
 display:none;
 }
 
@@ -558,7 +566,7 @@ font-weight:bold;
 /* entity_profile */
 .entity_profile {
 position:relative;
-width:74.702%;
+width:73%;
 min-height:123px;
 float:left;
 margin-bottom:18px;
@@ -629,9 +637,9 @@ font-style:italic;
 /*entity_actions*/
 .entity_actions {
 float:right;
-margin-left:2.35%;
+margin-left:2%;
 margin-bottom:18px;
-width:21%;
+min-width:21%;
 }
 .entity_actions h2 {
 display:none;
@@ -1325,16 +1333,16 @@ clear:both;
 margin-bottom:0;
 }
 
-#form_settings_design #settings_design_background-image img {
+#settings_design_background-image img {
 max-width:480px;
 max-height:480px;
 }
 
-#form_settings_design #settings_design_color .form_data,
-#form_settings_design #color-picker {
+#settings_design_color .form_data,
+#color-picker {
 float:left;
 }
-#form_settings_design #settings_design_color .form_data {
+#settings_design_color .form_data {
 width:400px;
 margin-right:28px;
 }
index 8799b0b09e69ede23e611f967910fa0a6e6d8023..6edc66ad26ec818bf4ea46fb656b86dd7718224d 100644 (file)
@@ -135,7 +135,8 @@ button.close,
 .form_group_leave input.submit,
 .form_user_unsubscribe input.submit,
 .form_group_join input.submit,
-.form_user_subscribe input.submit {
+.form_user_subscribe input.submit,
+.entity_subscribe a {
 background-image:url(../../base/images/icons/icons-01.gif);
 background-repeat:no-repeat;
 background-color:transparent;
@@ -178,6 +179,12 @@ background-color:rgba(255, 255, 255, 0.7);
 #site_nav_local_views .current a {
 text-shadow: rgba(194,194,194,0.5) 1px 1px 1px;
 }
+.processing {
+background-image:url(../../base/images/icons/icon_processing.gif);
+background-repeat:no-repeat;
+background-position:47% 47%;
+}
+
 
 .error {
 background-color:#F7E8E8;
@@ -216,7 +223,8 @@ background-position:0 1px;
 .form_group_join input.submit,
 .form_group_leave input.submit,
 .form_user_subscribe input.submit,
-.form_user_unsubscribe input.submit {
+.form_user_unsubscribe input.submit,
+.entity_subscribe a {
 background-color:#AAAAAA;
 color:#FFFFFF;
 }
@@ -225,7 +233,8 @@ color:#FFFFFF;
 background-position:5px -1246px;
 }
 .form_group_join input.submit,
-.form_user_subscribe input.submit {
+.form_user_subscribe input.submit,
+.entity_subscribe a {
 background-position:5px -1181px;
 }
 
@@ -328,3 +337,17 @@ background-position:10% -187px;
 .pagination .nav_next a {
 background-position:105% -252px;
 }
+.pagination .nav .processing {
+background-image:url(../../base/images/icons/icon_processing.gif);
+box-shadow:none;
+-moz-box-shadow:none;
+-webkit-box-shadow:none;
+outline:none;
+}
+.pagination .nav_next a.processing {
+background-position:90% 47%;
+}
+.pagination .nav_prev a.processing {
+background-position:10% 47%;
+}
+