diff --git a/conf/data/configs/application.ini b/conf/data/configs/application.ini index e533665..0dfec1b 100644 --- a/conf/data/configs/application.ini +++ b/conf/data/configs/application.ini @@ -138,7 +138,7 @@ sign_me_auto = "DefaultOff" enable = On ; List of enabled plugins -enabled_list = "ynh-login-mapping" +enabled_list = "PLUGINSTOENABLE" [defaults] ; Editor mode used by default (Plain, Html, HtmlForced or PlainForced) diff --git a/manifest.json b/manifest.json index c95de22..e184a63 100644 --- a/manifest.json +++ b/manifest.json @@ -35,7 +35,7 @@ { "name": "is_public", "ask": { - "en": "Is it a public application ?", + "en": "Is it a public application?", "fr": "Est-ce une page publique ?" }, "choices": ["Yes", "No"], @@ -48,6 +48,15 @@ "en": "Choose a strong password for the 'admin' user", "fr": "Choisissez un mot de passe fort pour l'administrateur 'admin'" } + }, + { + "name": "ldap", + "ask": { + "en": "Do you want to add YunoHost users to the recipients suggestions?", + "fr": "Souhaitez-vous ajouter les utilisateurs YunoHost dans les suggestions de destinataires ?" + }, + "choices": ["Yes", "No"], + "default": "Yes" } ] } diff --git a/scripts/install b/scripts/install index 8d4feb1..67e4935 100644 --- a/scripts/install +++ b/scripts/install @@ -1,132 +1,132 @@ #!/bin/bash - +set -e app=rainloop # Retrieve arguments -domain=$1 -path=$2 -is_public=$3 -password=$4 + domain=$1 + path=$2 + is_public=$3 + password=$4 + ldap=$5 # Removal of trailing / -if [ $path = "/" ] -then - #sitename="root" - echo "Installation on the root of the domain" -else - # sitename == path without any "/" - #sitename=$(echo $path | cut -d '/' -f 2) - # Removal of trailing / - # path can be null but not really an issue for the remaining commands - path=${path%/} -fi + if [ $path = "/" ] + then + echo "Installation on the root of the domain" + else + path=${path%/} + fi # Check domain/path availability -sudo yunohost app checkurl $domain$path -a rainloop -if [[ ! $? -eq 0 ]]; then - exit 1 -fi + sudo yunohost app checkurl $domain$path -a rainloop + if [[ ! $? -eq 0 ]]; then + exit 1 + fi -# Generate random password -db_pwd=$(dd if=/dev/urandom bs=1 count=200 2> /dev/null | tr -c -d 'A-Za-z0-9' | sed -n 's/\(.\{24\}\).*/\1/p') +# Generate random password, use 'rainloop' as database name and user and intialize databse + db_pwd=$(dd if=/dev/urandom bs=1 count=200 2> /dev/null | tr -c -d 'A-Za-z0-9' | sed -n 's/\(.\{24\}\).*/\1/p') + db_user=$app + sudo yunohost app initdb $db_user -p $db_pwd + sudo yunohost app setting $app mysqlpwd -v $db_pwd -# Use 'rainloop' as database name and user -db_user=$app +# Create the final path and copy sources + final_path=/var/www/$app + rainloop_path=${final_path}/app -# Initialize database and store mysql password for upgrade -sudo yunohost app initdb $db_user -p $db_pwd -sudo yunohost app setting rainloop mysqlpwd -v $db_pwd + sudo rm -rf $final_path + sudo mkdir -p $final_path + sudo mkdir -p $rainloop_path -#mysql -u $db_user -p$db_pwd $db_user < ../sources/plugins/automatic_addressbook/SQL/mysql.initial.sql - -# Copy files to the right place -final_path=/var/www/$app -rainloop_path=${final_path}/app -#rainloop_path=${final_path} - -sudo rm -rf $final_path -sudo mkdir -p $final_path -sudo mkdir -p $rainloop_path - -# Use of latest community edition -sudo unzip ../sources/rainloop-community.zip -d $rainloop_path/ + # Use of latest community edition + sudo unzip ../sources/rainloop-community.zip -d $rainloop_path/ + + # Install plugins + sudo mkdir -p $rainloop_path/data/_data_/_default_/plugins + sudo cp -rf ../sources/plugins/ynh-login-mapping $rainloop_path/data/_data_/_default_/plugins/. + sudo cp -rf ../sources/plugins/ynh-ldap-addressbooks $rainloop_path/data/_data_/_default_/plugins/. # Autoconfig -sudo mkdir -p $rainloop_path/data/_data_/_default_/configs/ -application_file=$rainloop_path/data/_data_/_default_/configs/application.ini -if [ $(echo $LANG | cut -c1-2) == "fr" ] -then - lang=fr -else - lang=en -fi -sudo cp ../conf/data/configs/application.ini $application_file -sudo sed -i "s@domain.tld@$domain@g" $application_file -sudo sed -i "s@MYSQLUSER@$db_user@g" $application_file -sudo sed -i "s@MYSQLPASSWORD@$db_pwd@g" $application_file -sudo sed -i "s@LANGTOCHANGE@$lang@g" $application_file + sudo mkdir -p $rainloop_path/data/_data_/_default_/configs/ + application_file=$rainloop_path/data/_data_/_default_/configs/application.ini + + # Set lang + if [ $(echo $LANG | cut -c1-2) == "fr" ] + then + lang=fr + else + lang=en + fi + + # Set plugins + plugins="ynh-login-mapping" + if [ "$ldap" = "Yes" ]; + then + plugins="$plugins,ynh-ldap-addressbooks" + fi + sudo yunohost app setting $app plugins -v $plugins + + sudo cp ../conf/data/configs/application.ini $application_file + sudo sed -i "s@domain.tld@$domain@g" $application_file + sudo sed -i "s@MYSQLUSER@$db_user@g" $application_file + sudo sed -i "s@MYSQLPASSWORD@$db_pwd@g" $application_file + sudo sed -i "s@LANGTOCHANGE@$lang@g" $application_file + sudo sed -i "s@PLUGINSTOENABLE@$plugins@g" $application_file # Set admin password -sudo php ../conf/config.php --index="$rainloop_path/index.php" --password="$password" + sudo php ../conf/config.php --index="$rainloop_path/index.php" --password="$password" # Add default domain configs by looping through all the domains already added -sudo mkdir -p $rainloop_path/data/_data_/_default_/domains/ - -# get list of ldap domains -alldomains=`ldapsearch -LLL -x -b ou=domains,dc=yunohost,dc=org -s one "objectclass=top" virtualdomain | grep -v "dn:" | sed "s/virtualdomain://" ` -for alldomain in $alldomains ; do - sudo cp ../conf/data/domains/domain.tld.ini $rainloop_path/data/_data_/_default_/domains/$alldomain.ini - sudo sed -i "s@domain.tld@$alldomain@g" $rainloop_path/data/_data_/_default_/domains/$alldomain.ini -done -sudo cp ../conf/data/domains/disabled $rainloop_path/data/_data_/_default_/domains/disabled - -# now install ynh plugins: -sudo mkdir -p $rainloop_path/data/_data_/_default_/plugins -sudo cp -rf ../sources/plugins/ynh-login-mapping $rainloop_path/data/_data_/_default_/plugins/. + sudo mkdir -p $rainloop_path/data/_data_/_default_/domains/ + # get list of ldap domains + alldomains=`ldapsearch -LLL -x -b ou=domains,dc=yunohost,dc=org -s one "objectclass=top" virtualdomain | grep -v "dn:" | sed "s/virtualdomain://" ` + for alldomain in $alldomains ; do + sudo cp ../conf/data/domains/domain.tld.ini $rainloop_path/data/_data_/_default_/domains/$alldomain.ini + sudo sed -i "s@domain.tld@$alldomain@g" $rainloop_path/data/_data_/_default_/domains/$alldomain.ini + done + sudo cp ../conf/data/domains/disabled $rainloop_path/data/_data_/_default_/domains/disabled # Hooks for domains are not implemented yet, so new domains will not be added automatically -# install SSO and auto version -if [ $final_path == $rainloop_path ] -then - # use modified version of master index.php that implement sso - sudo cp ../sources/sso/index.php $final_path/index.php -else - # use only sso on master - sudo cp ../sources/sso/sso.php $final_path/index.php - sudo cp ../sources/patch/index_auto_version.php $rainloop_path/index.php -fi -sudo sed -i "s@domain.tld@$domain@g" $final_path/index.php -sudo sed -i "s@PATHTOCHANGE@$path@g" $final_path/index.php +# install SSO and auto version - at the moment the index is the SSO and rainloop is installed in /app + if [ $final_path == $rainloop_path ] + then + # use modified version of master index.php that implement sso + sudo cp ../sources/sso/index.php $final_path/index.php + else + # use only sso on master + sudo cp ../sources/sso/sso.php $final_path/index.php + sudo cp ../sources/patch/index_auto_version.php $rainloop_path/index.php + fi + sudo sed -i "s@domain.tld@$domain@g" $final_path/index.php + sudo sed -i "s@PATHTOCHANGE@$path@g" $final_path/index.php # Set permissions to rainloop directory -sudo chown -R www-data:www-data $final_path + sudo chown -R www-data:www-data $final_path # Install Nginx configuration file -nginx_conf_file=/etc/nginx/conf.d/$domain.d/$app.conf -sudo cp ../conf/nginx.conf $nginx_conf_file -sudo sed -i "s@PATHTOCHANGE@$path@g" $nginx_conf_file -sudo sed -i "s@ALIASTOCHANGE@$final_path/@g" $nginx_conf_file -sudo sed -i "s@NAMETOCHANGE@$app@g" $nginx_conf_file -sudo chown root: $nginx_conf_file -sudo chmod 644 $nginx_conf_file + nginx_conf_file=/etc/nginx/conf.d/$domain.d/$app.conf + sudo cp ../conf/nginx.conf $nginx_conf_file + sudo sed -i "s@PATHTOCHANGE@$path@g" $nginx_conf_file + sudo sed -i "s@ALIASTOCHANGE@$final_path/@g" $nginx_conf_file + sudo sed -i "s@NAMETOCHANGE@$app@g" $nginx_conf_file + sudo chown root: $nginx_conf_file + sudo chmod 644 $nginx_conf_file -finalphpconf=/etc/php5/fpm/pool.d/$app.conf -sudo cp ../conf/php-fpm.conf $finalphpconf -sudo sed -i "s@NAMETOCHANGE@$app@g" $finalphpconf -sudo chown root: $finalphpconf -sudo chmod 644 $finalphpconf + finalphpconf=/etc/php5/fpm/pool.d/$app.conf + sudo cp ../conf/php-fpm.conf $finalphpconf + sudo sed -i "s@NAMETOCHANGE@$app@g" $finalphpconf + sudo chown root: $finalphpconf + sudo chmod 644 $finalphpconf # Make app public if necessary -sudo yunohost app setting $app is_public -v "$is_public" -if [ "$is_public" = "Yes" ]; -then - sudo yunohost app setting $app skipped_uris -v "/" -fi - + sudo yunohost app setting $app is_public -v "$is_public" + if [ "$is_public" = "Yes" ]; + then + sudo yunohost app setting $app skipped_uris -v "/" + fi # Reload Nginx and regenerate SSOwat conf -sudo service php5-fpm reload -sudo service nginx reload -sudo yunohost app ssowatconf + sudo service php5-fpm reload + sudo service nginx reload + sudo yunohost app ssowatconf \ No newline at end of file diff --git a/scripts/remove b/scripts/remove index d3c64c6..5ae71ab 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,5 +1,5 @@ #!/bin/bash - +set -e app=rainloop db_user=$app diff --git a/scripts/upgrade b/scripts/upgrade index d62d07b..1d3fc33 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,71 +1,70 @@ #!/bin/bash - +set -e app=rainloop # Retrieve arguments -domain=$(sudo yunohost app setting $app domain) -path=$(sudo yunohost app setting $app path) -is_public=$(sudo yunohost app setting $app is_public) -dp_pwd=$(sudo yunohost app setting $app mysqlpwd) -db_user=$app + domain=$(sudo yunohost app setting $app domain) + path=$(sudo yunohost app setting $app path) + is_public=$(sudo yunohost app setting $app is_public) + dp_pwd=$(sudo yunohost app setting $app mysqlpwd) + db_user=$app + plugins=$(sudo yunohost app setting $app plugins) # no update for db now... -#root_pwd=$(sudo cat /etc/yunohost/mysql) -#mysql -u root -p$root_pwd -e "DROP DATABASE $db_name ; DROP USER $db_user@localhost ;" -#sudo yunohost app initdb $db_user -p $db_pwd -# Copy files to the right place -final_path=/var/www/$app -rainloop_path=${final_path}/app -#rainloop_path=${final_path} +# Create the final path and copy sources + final_path=/var/www/$app + rainloop_path=${final_path}/app -# no delete... we keep old install, the new is in a new path -#sudo rm -rf $final_path -#sudo mkdir -p $final_path -#sudo mkdir -p $rainloop_path + # the old version is not deleted... the new version is in a new path -# Use of latest community edition -sudo unzip ../sources/rainloop-community.zip -d $rainloop_path/ + # Use of latest community edition + sudo unzip ../sources/rainloop-community.zip -d $rainloop_path/ + + # Install plugins + sudo mkdir -p $rainloop_path/data/_data_/_default_/plugins + sudo cp -rf ../sources/plugins/ynh-login-mapping $rainloop_path/data/_data_/_default_/plugins/. -# update patch to auto load version. -sudo cp ../sources/patch/index_auto_version.php $rainloop_path/index.php + # Update patch to auto load version + sudo cp ../sources/patch/index_auto_version.php $rainloop_path/index.php -# update ynh plugins: -sudo mkdir -p $rainloop_path/data/_data_/_default_/plugins -sudo cp -rf ../sources/plugins/ynh-login-mapping $rainloop_path/data/_data_/_default_/plugins/. + # Update ynh plugins: + sudo mkdir -p $rainloop_path/data/_data_/_default_/plugins + sudo cp -rf ../sources/plugins/ynh-login-mapping $rainloop_path/data/_data_/_default_/plugins/. + sudo cp -rf ../sources/plugins/ynh-ldap-addressbooks $rainloop_path/data/_data_/_default_/plugins/. # update SSO and auto version -if [ $final_path == $rainloop_path ] -then - # use modified version of master index.php that implement sso - sudo cp ../sources/sso/index.php $final_path/index.php -else - # use only sso on master - sudo cp ../sources/sso/sso.php $final_path/index.php - sudo cp ../sources/patch/index_auto_version.php $rainloop_path/index.php -fi -sudo sed -i "s@domain.tld@$domain@g" $final_path/index.php -sudo sed -i "s@PATHTOCHANGE@$path@g" $final_path/index.php + if [ $final_path == $rainloop_path ] + then + # use modified version of master index.php that implement sso + sudo cp ../sources/sso/index.php $final_path/index.php + else + # use only sso on master + sudo cp ../sources/sso/sso.php $final_path/index.php + sudo cp ../sources/patch/index_auto_version.php $rainloop_path/index.php + fi + sudo sed -i "s@domain.tld@$domain@g" $final_path/index.php + sudo sed -i "s@PATHTOCHANGE@$path@g" $final_path/index.php # Set permissions to rainloop directory -sudo chown -R www-data:www-data $final_path + sudo chown -R www-data:www-data $final_path # Update Nginx configuration file -nginx_conf_file=/etc/nginx/conf.d/$domain.d/$app.conf -sudo cp ../conf/nginx.conf $nginx_conf_file -sudo sed -i "s@PATHTOCHANGE@$path@g" $nginx_conf_file -sudo sed -i "s@ALIASTOCHANGE@$final_path/@g" $nginx_conf_file -sudo sed -i "s@NAMETOCHANGE@$app@g" $nginx_conf_file -sudo chown root: $nginx_conf_file -sudo chmod 644 $nginx_conf_file + nginx_conf_file=/etc/nginx/conf.d/$domain.d/$app.conf + sudo cp ../conf/nginx.conf $nginx_conf_file + sudo sed -i "s@PATHTOCHANGE@$path@g" $nginx_conf_file + sudo sed -i "s@ALIASTOCHANGE@$final_path/@g" $nginx_conf_file + sudo sed -i "s@NAMETOCHANGE@$app@g" $nginx_conf_file + sudo chown root: $nginx_conf_file + sudo chmod 644 $nginx_conf_file -finalphpconf=/etc/php5/fpm/pool.d/$app.conf -sudo cp ../conf/php-fpm.conf $finalphpconf -sudo sed -i "s@NAMETOCHANGE@$app@g" $finalphpconf -sudo chown root: $finalphpconf -sudo chmod 644 $finalphpconf + finalphpconf=/etc/php5/fpm/pool.d/$app.conf + sudo cp ../conf/php-fpm.conf $finalphpconf + sudo sed -i "s@NAMETOCHANGE@$app@g" $finalphpconf + sudo chown root: $finalphpconf + sudo chmod 644 $finalphpconf # Reload Nginx and regenerate SSOwat conf -sudo service php5-fpm reload -sudo service nginx reload -sudo yunohost app ssowatconf + sudo service php5-fpm reload + sudo service nginx reload + sudo yunohost app ssowatconf \ No newline at end of file diff --git a/sources/patch/index_auto_version.php b/sources/patch/index_auto_version.php index 887a5fa..22f604e 100644 --- a/sources/patch/index_auto_version.php +++ b/sources/patch/index_auto_version.php @@ -1,18 +1,18 @@ - + diff --git a/sources/plugins/ynh-ldap-addressbooks/README b/sources/plugins/ynh-ldap-addressbooks/README new file mode 100644 index 0000000..b6fece7 --- /dev/null +++ b/sources/plugins/ynh-ldap-addressbooks/README @@ -0,0 +1 @@ +Plugin which allows to suggess email from ynh ldap diff --git a/sources/plugins/ynh-ldap-addressbooks/VERSION b/sources/plugins/ynh-ldap-addressbooks/VERSION new file mode 100644 index 0000000..49d5957 --- /dev/null +++ b/sources/plugins/ynh-ldap-addressbooks/VERSION @@ -0,0 +1 @@ +0.1 diff --git a/sources/plugins/ynh-ldap-addressbooks/YnhLdapAddressbooks.php b/sources/plugins/ynh-ldap-addressbooks/YnhLdapAddressbooks.php new file mode 100644 index 0000000..c0294e1 --- /dev/null +++ b/sources/plugins/ynh-ldap-addressbooks/YnhLdapAddressbooks.php @@ -0,0 +1,170 @@ +ldapSearch ( $oAccount, $sQuery, $iLimit ); + + $aResult = \RainLoop\Utils::RemoveSuggestionDuplicates ( $aResult ); + if ($iLimit < \count ( $aResult )) { + $aResult = \array_slice ( $aResult, 0, $iLimit ); + } + + return $aResult; + } + + /** + * + * OK search in ldap. + * match email or displayName... + * + * @param \RainLoop\Model\Account $oAccount + * @param string $sQuery + * + * @return array + */ + private function ldapSearch($oAccount, $sQuery, $iLimit) { + $sSearchEscaped = $this->escape ( $sQuery ); + + $aResult = array (); + $oCon = @\ldap_connect (); + if (! $oCon) { + $this->oLogger->Write ( 'YnhLdapAddressbooks: Could not connect to LDAP server', \MailSo\Log\Enumerations\Type::ERROR ); + return $aResult; + } + + @\ldap_set_option ( $oCon, LDAP_OPT_PROTOCOL_VERSION, 3 ); + + if (! ldap_bind ( $oCon )) { + // bizard... ca renvoie false.... mais ca marche.... + // $this->logLdapError ( $oCon, 'ldap_bind' ); + // $this->Manager()->Actions()->Logger()->Write('YnhLdapAdressbooks: Could not bind to LDAP server', \MailSo\Log\Enumerations\Type::ERROR); + // return $aResult; + } + + $this->oLogger->Write ( 'YnhLdapAddressbooks: connected to LDAP', \MailSo\Log\Enumerations\Type::INFO, 'LDAP' ); + + $sSearchDn = 'dc=yunohost,dc=org'; + + // on veut chercher parmis mail et nom utilisateur... + $sFilter = '(&(objectClass=inetOrgPerson)'; + $sFilter .= '(|'; + $sFilter .= '(mail=*' . $sSearchEscaped . '*)'; + $sFilter .= '(displayName=*' . $sSearchEscaped . '*)'; + $sFilter .= '))'; + + $aItems = array ( + 'mail', + 'displayName' + ); + + $this->oLogger->Write ( 'YnhLdapAddressbooks: ldap_search : ' . $sSearchDn . ' / ' . $sFilter, \MailSo\Log\Enumerations\Type::INFO, 'LDAP' ); + + $oS = @\ldap_search ( $oCon, $sSearchDn, $sFilter, $aItems, 0, $iLimit, $iLimit ); + if ($oS) { + $aEntries = @\ldap_get_entries ( $oCon, $oS ); + $this->oLogger->Write ( 'YnhLdapAddressbooks: ldap_search => ' . var_export ( $aEntries ), \MailSo\Log\Enumerations\Type::INFO, 'LDAP' ); + + if (is_array ( $aEntries )) { + if (isset ( $aEntries ['count'] )) { + unset ( $aEntries ['count'] ); + } + + foreach ( $aEntries as $aItem ) { + $sName = \trim ( $aItem ['displayname'] [0] ); + if (isset ( $aItem ['mail'] ['count'] )) { + unset ( $aItem ['mail'] ['count'] ); + } + foreach ( $aItem ['mail'] as $sEmail ) { + $sEmail = \trim ( $sEmail ); + if (! empty ( $sEmail )) { + $aResult [] = array ( + $sEmail, + $sName + ); + } + } + } + } else { + $this->logLdapError ( $oCon, 'ldap_get_entries' ); + } + } else { + $this->logLdapError ( $oCon, 'ldap_search' ); + } + + return $aResult; + } + + /** + * + * @param string $sStr + * + * @return string + */ + private function escape($sStr) { + $aNewChars = array (); + $aChars = array ( + '\\', + '*', + ' (', + ')', + \chr ( 0 ) + ); + + foreach ( $aChars as $iIndex => $sValue ) { + $aNewChars [$iIndex] = '\\' . \str_pad ( \dechex ( \ord ( $sValue ) ), 2, '0' ); + } + return \str_replace ( $aChars, $aNewChars, $sStr ); + } + + /** + * + * @param mixed $oCon + * @param string $sCmd + * + * @return string + */ + private function logLdapError($oCon, $sCmd) { + if ($this->oLogger) { + $sError = $oCon ? @\ldap_error ( $oCon ) : ''; + $iErrno = $oCon ? @\ldap_errno ( $oCon ) : 0; + + $this->oLogger->Write ( $sCmd . ' error: ' . $sError . ' (' . $iErrno . ')', \MailSo\Log\Enumerations\Type::WARNING, 'LDAP' ); + } + } + + /** + * + * @param \MailSo\Log\Logger $oLogger + * + * @return \LdapContactsSuggestions + */ + /** + * + * @param \MailSo\Log\Logger $oLogger + */ + public function SetLogger($oLogger) { + $this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null; + } +} +?> diff --git a/sources/plugins/ynh-ldap-addressbooks/index.php b/sources/plugins/ynh-ldap-addressbooks/index.php new file mode 100644 index 0000000..f7e3368 --- /dev/null +++ b/sources/plugins/ynh-ldap-addressbooks/index.php @@ -0,0 +1,37 @@ +addHook ( 'main.fabrica', 'MainFabrica' ); + } + + /** + * test if ldap is supported (but with ynh it nead ;) ) + * + * @return string + */ + public function Supported() { + if (! \function_exists ( 'ldap_connect' )) { + return 'The LDAP PHP exention must be installed to use this plugin'; + } + return ''; + } + + /** + * + * @param string $sName + * @param mixed $mResult + */ + public function MainFabrica($sName, &$mResult) { + if ($sName === 'suggestions') { + include_once __DIR__ . '/YnhLdapAddressbooks.php'; + + if (! \is_array ( $mResult )) { + $mResult = array (); + } + + $oProvider = new YnhLdapAddressbooks (); + $mResult [] = $oProvider; + } + } +} +?> diff --git a/sources/sso/index.php b/sources/sso/index.php index f89e738..c88e331 100644 --- a/sources/sso/index.php +++ b/sources/sso/index.php @@ -1,35 +1,35 @@ - +