From 7551464d239a77d3f23b02a8f84ea78ebc282b2e Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 17 Nov 2009 16:55:45 -0800 Subject: [PATCH 01/21] Get rid of empty select in theme dropdown --- actions/designadminpanel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/designadminpanel.php b/actions/designadminpanel.php index dcf5605af1..9845ddb547 100644 --- a/actions/designadminpanel.php +++ b/actions/designadminpanel.php @@ -179,7 +179,7 @@ class DesignAdminPanelForm extends Form $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'); From 7dfce35bea3e9476358048083ed469b2674b41a4 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Tue, 17 Nov 2009 23:22:19 -0500 Subject: [PATCH 02/21] (Theoretically) allow users to change their passwords. I cannot test this... but I hope it works :-) --- .../LdapAuthenticationPlugin.php | 164 +++++++++++++++++- plugins/LdapAuthentication/README | 8 +- 2 files changed, 163 insertions(+), 9 deletions(-) diff --git a/plugins/LdapAuthentication/LdapAuthenticationPlugin.php b/plugins/LdapAuthentication/LdapAuthenticationPlugin.php index 865154730f..ad5dd3a022 100644 --- a/plugins/LdapAuthentication/LdapAuthenticationPlugin.php +++ b/plugins/LdapAuthentication/LdapAuthenticationPlugin.php @@ -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 --- + * --- ammended 20030625 by S C Rigler --- + * + * @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; + } } diff --git a/plugins/LdapAuthentication/README b/plugins/LdapAuthentication/README index dc3f4ba884..2226159c2e 100644 --- a/plugins/LdapAuthentication/README +++ b/plugins/LdapAuthentication/README @@ -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') )); From 7e0af928132c8eda2f25943b9a316e8ddf6f9a41 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 18 Nov 2009 00:00:05 -0800 Subject: [PATCH 03/21] First draft of the admin panel for site design --- actions/designadminpanel.php | 390 ++++++++++++++++++++++++++++++++++- lib/form.php | 14 +- 2 files changed, 398 insertions(+), 6 deletions(-) diff --git a/actions/designadminpanel.php b/actions/designadminpanel.php index 9845ddb547..6b40ae0214 100644 --- a/actions/designadminpanel.php +++ b/actions/designadminpanel.php @@ -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,6 +392,9 @@ class DesignAdminPanelForm extends Form function formData() { + + $design = $this->out->design; + $themes = Theme::listAvailable(); asort($themes); @@ -175,14 +402,158 @@ class DesignAdminPanelForm extends Form $themes = array_combine($themes, $themes); $this->out->elementStart('ul', 'form_data'); - $this->out->elementStart('li'); + $this->out->elementStart('li'); $this->out->dropdown('theme', _('Theme'), $themes, _('Theme for the site.'), false, $this->value('theme')); - $this->out->elementEnd('li'); + + $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->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 +597,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')); } } diff --git a/lib/form.php b/lib/form.php index 87b7a5cba9..868c986b93 100644 --- a/lib/form.php +++ b/lib/form.php @@ -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 * From 904baf4d27fa9490938f3e355c0fd43c3deeef7e Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Wed, 18 Nov 2009 08:25:58 +0000 Subject: [PATCH 04/21] Missing quotes in postgres db create script --- db/statusnet_pg.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/statusnet_pg.sql b/db/statusnet_pg.sql index 7b0e5313ce..d4b7b66144 100644 --- a/db/statusnet_pg.sql +++ b/db/statusnet_pg.sql @@ -571,7 +571,7 @@ 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'*/, From 12025f43252d5b689a8429c8e892fda4b67f0d8d Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 09:06:46 +0000 Subject: [PATCH 05/21] Relaxed the CSS selector for design settings so it can be used in different forms. --- theme/base/css/display.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 96e169d6dc..08f20ed954 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -1325,16 +1325,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; } From bbead9d71b75cfd1c7e7521c6649d38c9b92f3ab Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 09:21:52 +0000 Subject: [PATCH 06/21] Relaxed the width for form select --- theme/base/css/display.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 08f20ed954..bfd9b0b279 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -127,6 +127,9 @@ width:39%; .form_settings .form_data textarea { width:63%; } +.form_settings .form_data select { +width:auto; +} .form_settings .form_data input.submit { margin-left:0; From c988161c3dcc1bf33c868a12f030e909604abdd1 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 09:23:06 +0000 Subject: [PATCH 07/21] Separated width selectors for form_data form controls --- theme/base/css/display.css | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/theme/base/css/display.css b/theme/base/css/display.css index bfd9b0b279..1057572da5 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -122,14 +122,13 @@ float:left; .form_settings .form_data input { margin-left:1.795%; float:left; +} +.form_settings .form_data input { width:39%; } .form_settings .form_data textarea { width:63%; } -.form_settings .form_data select { -width:auto; -} .form_settings .form_data input.submit { margin-left:0; From 4fc99f8246e166da537b9a025e629677c3ae2ef3 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 09:47:04 +0000 Subject: [PATCH 08/21] Updated admin design form markup --- actions/designadminpanel.php | 11 +++++++++++ theme/base/css/display.css | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/actions/designadminpanel.php b/actions/designadminpanel.php index 6b40ae0214..d1aadc8c27 100644 --- a/actions/designadminpanel.php +++ b/actions/designadminpanel.php @@ -401,6 +401,9 @@ class DesignAdminPanelForm extends Form $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'); @@ -408,7 +411,14 @@ class DesignAdminPanelForm extends Form $themes, _('Theme for the site.'), 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')); @@ -474,6 +484,7 @@ class DesignAdminPanelForm extends Form } $this->out->elementEnd('ul'); + $this->out->elementEnd('fieldset'); $this->out->elementStart('fieldset', array('id' => 'settings_design_color')); $this->out->element('legend', null, _('Change colours')); diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 1057572da5..2df322f133 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -167,7 +167,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; } From 9e756d6b152948d1a1df5da8b1eb5eb40e4cde0c Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 09:56:52 +0000 Subject: [PATCH 09/21] Updated default theme to match identica theme --- theme/default/css/display.css | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/theme/default/css/display.css b/theme/default/css/display.css index 8799b0b09e..6edc66ad26 100644 --- a/theme/default/css/display.css +++ b/theme/default/css/display.css @@ -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%; +} + From b5ed698bd24fa6587f9b841b49c09698504477ea Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:35:27 +0000 Subject: [PATCH 10/21] Setting the width to particular form_settings inputs to auto --- theme/base/css/display.css | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 2df322f133..ccac7af2ca 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -126,6 +126,11 @@ 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%; } @@ -561,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; @@ -632,9 +637,9 @@ font-style:italic; /*entity_actions*/ .entity_actions { float:right; -margin-left:2.35%; +margin-left:2%; margin-bottom:18px; -width:21%; +max-width:25%; } .entity_actions h2 { display:none; From 730b1a211f9d28dc33c67cacfda8538ec7196e8f Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:42:43 +0000 Subject: [PATCH 11/21] Added on click event to open up anchors in notice items in a new window for the Realtime plugin's pop-up window. --- plugins/Realtime/realtimeupdate.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 9b9991b9ee..3a1e9683fe 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -208,6 +208,12 @@ RealtimeUpdate = { 'left':'auto', 'right':'0' }); + + $('.notices .entry-title a, .notices .entry-content a').bind('click', function() { + window.open(this.href, ''); + + return false; + }); } } From edf9b38637cd48b45c9675247bb3243138d98ffb Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:43:55 +0000 Subject: [PATCH 12/21] Changed window open name to '' because IE doesn't compute names that include the '-' character. --- plugins/Realtime/realtimeupdate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 3a1e9683fe..aa4c6c15f0 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -180,7 +180,7 @@ RealtimeUpdate = { RT.click(function() { window.open(url, - timeline, + '', 'toolbar=no,resizable=yes,scrollbars=yes,status=yes,width=500,height=550'); return false; From 4fbb6b0dfb9ee74accd23d680d45d1cace91974a Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:46:55 +0000 Subject: [PATCH 13/21] Removed setTimeout. It was initially intended to prevent dupes but this is not the case with 0.9.x's util.js as opposed to 0.8.x, where it didn't properly check if a given notice id is already in the list --- plugins/Realtime/realtimeupdate.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index aa4c6c15f0..1658880548 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -58,23 +58,21 @@ 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; - } + // 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); - SN.U.NoticeReply(); + 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(); - RealtimeUpdate._updatecounter += 1; - document.title = '('+RealtimeUpdate._updatecounter+') ' + DT; - }, 500); + RealtimeUpdate._updatecounter += 1; + document.title = '('+RealtimeUpdate._updatecounter+') ' + DT; }, makeNoticeItem: function(data) From 908deed8989ec55502e70e8a75823511fa9728e7 Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Wed, 18 Nov 2009 10:48:17 +0000 Subject: [PATCH 14/21] Added documentation in the README for what the 'language' setting actually does. i.e. in practice, nothing. --- README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README b/README index fb78ab01d2..eb1fb8cd70 100644 --- 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: From 5e0fb1ddfc877cec5b367857a58f621f47067ddc Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:49:41 +0000 Subject: [PATCH 15/21] Added a call to NoticeFavor() --- plugins/Realtime/realtimeupdate.js | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 1658880548..3c5d37f793 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -70,6 +70,7 @@ RealtimeUpdate = { $("#notices_primary .notice:first").css({display:"none"}); $("#notices_primary .notice:first").fadeIn(1000); SN.U.NoticeReply(); + SN.U.NoticeFavor(); RealtimeUpdate._updatecounter += 1; document.title = '('+RealtimeUpdate._updatecounter+') ' + DT; From 0c81f39bee37e288ad6d56091884da61b96637c5 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:53:48 +0000 Subject: [PATCH 16/21] Added check to see whether window has focus --- plugins/Realtime/realtimeupdate.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 3c5d37f793..d77a95f7ad 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -34,6 +34,7 @@ RealtimeUpdate = { _favorurl: '', _deleteurl: '', _updatecounter: 0, + _windowhasfocus: false, init: function(userid, replyurl, favorurl, deleteurl) { @@ -44,6 +45,8 @@ RealtimeUpdate = { DT = document.title; + $(window).bind('focus', function(){ RealtimeUpdate._windowhasfocus = true; }); + $(window).blur(function() { $('#notices_primary .notice').removeClass('mark-top'); @@ -51,6 +54,7 @@ RealtimeUpdate = { RealtimeUpdate._updatecounter = 0; document.title = DT; + RealtimeUpdate._windowhasfocus = false; return false; }); @@ -72,8 +76,10 @@ RealtimeUpdate = { SN.U.NoticeReply(); SN.U.NoticeFavor(); - RealtimeUpdate._updatecounter += 1; - document.title = '('+RealtimeUpdate._updatecounter+') ' + DT; + if (RealtimeUpdate._windowhasfocus === false) { + RealtimeUpdate._updatecounter += 1; + document.title = '('+RealtimeUpdate._updatecounter+') ' + DT; + } }, makeNoticeItem: function(data) From 23367ecdcf3146fe4a8d294e95d908f9c4882361 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:54:57 +0000 Subject: [PATCH 17/21] Setting max notice count in order not to freak out the browser with memory issues. It removes the node and unbinds the previously assigned events. --- plugins/Realtime/realtimeupdate.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index d77a95f7ad..8e7383a027 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -34,6 +34,7 @@ RealtimeUpdate = { _favorurl: '', _deleteurl: '', _updatecounter: 0, + _maxnotices: 50, _windowhasfocus: false, init: function(userid, replyurl, favorurl, deleteurl) @@ -73,6 +74,14 @@ RealtimeUpdate = { $("#notices_primary .notices").prepend(noticeItem); $("#notices_primary .notice:first").css({display:"none"}); $("#notices_primary .notice:first").fadeIn(1000); + + 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(); + } + SN.U.NoticeReply(); SN.U.NoticeFavor(); From 51e4a45161f0f1cb1a63c3ac5b8748706876bed1 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 10:56:25 +0000 Subject: [PATCH 18/21] Changed from click to bind --- plugins/Realtime/realtimeupdate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 8e7383a027..4444d801d5 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -192,7 +192,7 @@ RealtimeUpdate = { }); $('#showstream #notices_primary').css({'margin-top':'18px'}); - RT.click(function() { + RT.bind('click', function() { window.open(url, '', 'toolbar=no,resizable=yes,scrollbars=yes,status=yes,width=500,height=550'); From d1d104bde2779a9373a07d3046bda0e129c6b309 Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Wed, 18 Nov 2009 11:15:05 +0000 Subject: [PATCH 19/21] Another syntax error in the postgres db create script --- db/statusnet_pg.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/statusnet_pg.sql b/db/statusnet_pg.sql index d4b7b66144..8dbaf85981 100644 --- a/db/statusnet_pg.sql +++ b/db/statusnet_pg.sql @@ -576,6 +576,6 @@ create table login_token ( 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) ); From 1c1c9ccc2a553587115969b460e0e444ef33fe1e Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 12:16:11 +0000 Subject: [PATCH 20/21] Settling on min-width for entity_actions because 1. better i18n 2. doesn't alter the width when the action is processed. --- theme/base/css/display.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theme/base/css/display.css b/theme/base/css/display.css index ccac7af2ca..e5f5df68cc 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -639,7 +639,7 @@ font-style:italic; float:right; margin-left:2%; margin-bottom:18px; -max-width:25%; +min-width:21%; } .entity_actions h2 { display:none; From 007418fdab8f9f0c718a18568bfbf4377bb85364 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 18 Nov 2009 12:46:36 +0000 Subject: [PATCH 21/21] Setting windowhasfocus to true by default --- plugins/Realtime/realtimeupdate.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 4444d801d5..d1cf1d5070 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -35,7 +35,7 @@ RealtimeUpdate = { _deleteurl: '', _updatecounter: 0, _maxnotices: 50, - _windowhasfocus: false, + _windowhasfocus: true, init: function(userid, replyurl, favorurl, deleteurl) { @@ -48,7 +48,7 @@ RealtimeUpdate = { $(window).bind('focus', function(){ RealtimeUpdate._windowhasfocus = true; }); - $(window).blur(function() { + $(window).bind('blur', function() { $('#notices_primary .notice').removeClass('mark-top'); $('#notices_primary .notice:first').addClass('mark-top');