1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/rainloop_ynh.git synced 2024-09-03 20:16:18 +02:00

Merge pull request #14 from YunoHost-Apps/master

update to latest improvements
This commit is contained in:
polytan02 2017-02-23 11:33:51 +00:00 committed by GitHub
commit e95c759bf0
31 changed files with 1419 additions and 153 deletions

View file

@ -1,50 +1,43 @@
# Rainloop for YunoHost
* [rainloop](http://rainloop.net/ )
* [rainloop](http://rainloop.net/ ): 1.10.5.192
## English
Rainloop is a lightweight webmail.
To configure it, go to http://DOMAIN.TLD/rainloop/?admin
To configure it, go to http://DOMAIN.TLD/rainloop/app/?admin
- The default login is : admin
- The default password is : 12345
- The default password is : Password chosen during install
- If you lost the admin password, you can retrieve it using ``sudo yunohost app settings rainloop password``
To configure your instance, go to the admin panel, then "Domains" and add a domain in accord with your mail server setup.
Each user can add a remote carddav server from their own parameters interface.
To access the database (required for contacts), the paramaters are the following :
- Database name : rainloop
- Password : the_database_password_indicated_at_installation
- If you use baikal, the CardDav address is: https://DOMAIN.TLD/baikal/card.php/addressbooks/USER/default/
- If you use NextCloud, the CardDav address is: https://DOMAIN.TLD/nextcloud/remote.php/carddav/addressbooks/USER/contacts
Once this is done in the admin interface, each user can add a remote carddav server from their own parameters interface.
If you use baikal, the CardDav address is :
https://DOMAIN.TLD/baikal/card.php/addressbooks/USER/default/
Rainloop saves your PGP private keys in the browser storage. This means that you will loose your private keys if you clear your browser storage (e.g., private browsing, different computer...). This packages integrates [PGPback by chtixof](https://github.com/chtixof/pgpback_ynh) so you can store your PGP private keys on the server securely. Go to **http://DOMAIN.TLD/rainloop/pgpback** to backup your PGP keys on the server or restore them.
- to upgrade the app once a new rainloop version is available, simply run in a local shell via ssh or otherwise :
``sudo yunohost app upgrade -u https://github.com/polytan02/rainloop_ynh rainloop``
To upgrade the app once a new rainloop version is available, simply run in a local shell via ssh or otherwise :
``sudo yunohost app upgrade -u https://github.com/YunoHost-Apps/rainloop_ynh rainloop``
## Français
Rainloop est un webmail simple et léger.
Pour le configurer après l'installation, veuillez vous rendre sur http://DOMAIN.TLD/rainloop/?admin
Pour le configurer après l'installation, veuillez vous rendre sur http://DOMAIN.TLD/rainloop/app/?admin
- Le nom d'utilisateur admin par défaut est : admin
- Le mot de passe admin par défaut est : 12345
- Le mot de passe admin par défaut est : Mot de passe choisi lors de l'installation
- Si vous avez oublié votre mot de passe, vous pouvez le retrouver avec ``sudo yunohost app settings rainloop password``
Pour configurer votre instance, connectez-vous en admin, puis allez dans "Domains" et ajoutez votre domaine en accord avec la configuration de votre serveur email.
Chaque utilisateur peut ajouter un carnet d'adresse distant CardDav via leur propre paramètres.
Pour accéder à la base de donnée (necessaire pour gérer les contacts), les paramètres sont les suivants :
- Nom de la base de donnée : rainloop
- Mot de passe : Le_mot_de_passe_de_la_base_de_donnée_renseigné_lors_de_l'installation
- Si vous utilisez Baikal, l'adresse à renseigner est du type : https://DOMAIN.TLD/baikal/card.php/addressbooks/UTILISATEUR/default/
- Si vous utilisez NextCloud, l'adresse à renseigner est du type : https://DOMAIN.TLD/nextcloud/remote.php/carddav/addressbooks/USER/contacts
Une fois ceci fait depuis l'interface d'administration, chaque utilisateur peut ajouter un carnet d'adresse distant CardDav via leur propre paramètres.
Si vous utilisez Baikal, l'adresse à renseigner est du type :
https://DOMAIN.TLD/baikal/card.php/addressbooks/UTILISATEUR/default/
Rainloop stocke les clés PGP privées dans le stockage de navigateur. Cela implique que vos clés seront perdues quand vous videz le stockage de navigateur (navigation incognito, changement d'ordinateur, ...). Ce paquet intègre [PGPback de chtixof](https://github.com/chtixof/pgpback_ynh) pour que vous puissiez stocker vos clés privées PGP de manière sécurisée sur le serveur. Rendez-vous **http://DOMAIN.TLD/rainloop/pgpback** pour stocker vos clés privées PGP sur le serveur ou les restaurer dans un nouveau navigateur.
- pour mettre à jour rainloop lorsqu'une nouvelle version est disponible, lancez en console locale (ssh ou autre) :
``sudo yunohost app upgrade -u https://github.com/polytan02/rainloop_ynh rainloop``
Pour mettre à jour rainloop lorsqu'une nouvelle version est disponible, lancez en console locale (ssh ou autre) :
``sudo yunohost app upgrade -u https://github.com/YunoHost-Apps/rainloop_ynh rainloop``

52
check_process Normal file
View file

@ -0,0 +1,52 @@
;; Test Rainloop LDAP suggestions
auto_remove=1
; Manifest
domain="domain.tld" (DOMAIN)
path="/rainloop" (PATH)
is_public="No" (PUBLIC|public=Yes|private=No)
password="password" (PASSWORD)
ldap="Yes"
lang="English"
; Checks
pkg_linter=1
setup_sub_dir=1
setup_root=1
setup_nourl=0
setup_private=1
setup_public=1
upgrade=1
backup_restore=1
multi_instance=0
wrong_user=0
wrong_path=1
incorrect_path=1
corrupt_source=0
fail_download_source=0
port_already_use=0
final_path_already_use=0
;; Test Rainloop no LDAP suggestions
auto_remove=1
; Manifest
domain="domain.tld" (DOMAIN)
path="/rainloop" (PATH)
is_public="No" (PUBLIC|public=Yes|private=No)
password="password" (PASSWORD)
ldap="No"
lang="English"
; Checks
pkg_linter=1
setup_sub_dir=1
setup_root=1
setup_nourl=0
setup_private=1
setup_public=1
upgrade=1
backup_restore=1
multi_instance=0
wrong_user=0
wrong_path=1
incorrect_path=1
corrupt_source=0
fail_download_source=0
port_already_use=0
final_path_already_use=0

27
conf/config.php Normal file
View file

@ -0,0 +1,27 @@
<?php
function arguments($argv) {
$_ARG = array();
foreach ($argv as $arg) {
if (ereg('--([^=]+)=(.*)',$arg,$reg)) {
$_ARG[$reg[1]] = $reg[2];
} elseif(ereg('^-([a-zA-Z0-9])',$arg,$reg)) {
$_ARG[$reg[1]] = 'true';
} else {
$_ARG['input'][]=$arg;
}
}
return $_ARG;
}
// get args:
$args = arguments($argv);
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
include $args['index'];
$oConfig = \RainLoop\Api::Config();
$oConfig->SetPassword($args['password']);
echo $oConfig->Save() ? 'Admin password updated' : 'Admin password not updated';
?>

View file

@ -0,0 +1,329 @@
; RainLoop Webmail configuration file
; Please don't add custom parameters here, those will be overwritten
[webmail]
; Text displayed as page title
title = "RainLoop Webmail"
; Text displayed on startup
loading_description = "RainLoop"
favicon_url = ""
; Theme used by default
theme = "Default"
; Allow theme selection on settings screen
allow_themes = On
allow_user_background = Off
; Language used by default
language = "LANGTOCHANGE"
; Admin Panel interface language
language_admin = "LANGTOCHANGE"
; Allow language selection on settings screen
allow_languages_on_settings = On
allow_additional_accounts = On
allow_additional_identities = On
; Number of messages displayed on page by default
messages_per_page = 20
; File size limit (MB) for file upload on compose screen
; 0 for unlimited.
attachment_size_limit = 25
[interface]
show_attachment_thumbnail = On
[branding]
login_logo = ""
login_background = ""
login_desc = ""
login_css = ""
login_powered = On
user_css = ""
user_logo = ""
user_logo_title = ""
user_logo_message = ""
user_iframe_message = ""
welcome_page_url = ""
welcome_page_display = "none"
[contacts]
; Enable contacts
enable = On
allow_sharing = On
allow_sync = On
sync_interval = 20
type = "mysql"
pdo_dsn = "mysql:host=127.0.0.1;port=3306;dbname=rainloop"
pdo_user = "MYSQLUSER"
pdo_password = "MYSQLPASSWORD"
suggestions_limit = 30
[security]
; Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery)
csrf_protection = On
custom_server_signature = "RainLoop"
x_frame_options_header = ""
openpgp = On
use_rsa_encryption = Off
; Login and password for web admin panel
admin_login = "admin"
admin_password = "12345"
; Access settings
allow_admin_panel = On
allow_two_factor_auth = Off
force_two_factor_auth = Off
allow_universal_login = Off
admin_panel_host = ""
core_install_access_domain = ""
[ssl]
; Require verification of SSL certificate used.
verify_certificate = Off
; Allow self-signed certificates. Requires verify_certificate.
allow_self_signed = On
; Location of Certificate Authority file on local filesystem (/etc/ssl/certs/ca-certificates.crt)
cafile = ""
; capath must be a correctly hashed certificate directory. (/etc/ssl/certs/)
capath = ""
[capa]
folders = On
composer = On
contacts = On
settings = On
quota = On
help = On
reload = On
search = On
search_adv = On
filters = On
x-templates = Off
dangerous_actions = On
message_actions = On
messagelist_actions = On
attachments_actions = On
[login]
default_domain = "domain.tld"
; Allow language selection on webmail login screen
allow_languages_on_login = On
determine_user_language = On
determine_user_domain = Off
welcome_page = Off
forgot_password_link_url = ""
registration_link_url = ""
; This option allows webmail to remember the logged in user
; once they closed the browser window.
;
; Values:
; "DefaultOff" - can be used, disabled by default;
; "DefaultOn" - can be used, enabled by default;
; "Unused" - cannot be used
sign_me_auto = "DefaultOff"
[plugins]
; Enable plugin support
enable = On
; List of enabled plugins
enabled_list = "PLUGINSTOENABLE"
[defaults]
; Editor mode used by default (Plain, Html, HtmlForced or PlainForced)
view_editor_type = "Html"
; layout: 0 - no preview, 1 - side preview, 2 - bottom preview
view_layout = 1
view_use_checkboxes = On
autologout = Off
show_images = Off
contacts_autosave = On
mail_use_threads = Off
mail_reply_same_folder = Off
[logs]
; Enable logging
enable = Off
; Logs entire request only if error occured (php requred)
write_on_error_only = Off
; Logs entire request only if php error occured
write_on_php_error_only = Off
; Logs entire request only if request timeout (in seconds) occured.
write_on_timeout_only = 0
; Required for development purposes only.
; Disabling this option is not recommended.
hide_passwords = On
time_offset = 0
session_filter = ""
; Log filename.
; For security reasons, some characters are removed from filename.
; Allows for pattern-based folder creation (see examples below).
;
; Patterns:
; {date:Y-m-d} - Replaced by pattern-based date
; Detailed info: http://www.php.net/manual/en/function.date.php
; {user:email} - Replaced by user's email address
; If user is not logged in, value is set to "unknown"
; {user:login} - Replaced by user's login (the user part of an email)
; If user is not logged in, value is set to "unknown"
; {user:domain} - Replaced by user's domain name (the domain part of an email)
; If user is not logged in, value is set to "unknown"
; {user:uid} - Replaced by user's UID regardless of account currently used
;
; {user:ip}
; {request:ip} - Replaced by user's IP address
;
; Others:
; {imap:login} {imap:host} {imap:port}
; {smtp:login} {smtp:host} {smtp:port}
;
; Examples:
; filename = "log-{date:Y-m-d}.txt"
; filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
; filename = "{user:email}-{date:Y-m-d}.txt"
filename = "log-{date:Y-m-d}.txt"
; Enable auth logging in a separate file (for fail2ban)
auth_logging = Off
auth_logging_filename = "fail2ban/auth-{date:Y-m-d}.txt"
auth_logging_format = "[{date:Y-m-d H:i:s}] Auth failed: ip={request:ip} user={imap:login} host={imap:host} port={imap:port}"
[debug]
; Special option required for development purposes
enable = Off
[social]
; Google
google_enable = Off
google_enable_auth = Off
google_enable_auth_fast = Off
google_enable_drive = Off
google_enable_preview = Off
google_client_id = ""
google_client_secret = ""
google_api_key = ""
; Facebook
fb_enable = Off
fb_app_id = ""
fb_app_secret = ""
; Twitter
twitter_enable = Off
twitter_consumer_key = ""
twitter_consumer_secret = ""
; Dropbox
dropbox_enable = Off
dropbox_api_key = ""
[cache]
; The section controls caching of the entire application.
;
; Enables caching in the system
enable = On
; Additional caching key. If changed, cache is purged
index = "v1"
; Can be: files, APC, memcache
fast_cache_driver = "files"
; Additional caching key. If changed, fast cache is purged
fast_cache_index = "v1"
; Browser-level cache. If enabled, caching is maintainted without using files
http = On
; Caching message UIDs when searching and sorting (threading)
server_uids = On
[labs]
; Experimental settings. Handle with care.
;
ignore_folders_subscription = Off
check_new_password_strength = On
update_channel = "stable"
allow_gravatar = On
allow_prefetch = On
allow_smart_html_links = On
cache_system_data = On
date_from_headers = Off
autocreate_system_folders = On
allow_message_append = Off
disable_iconv_if_mbstring_supported = Off
login_fault_delay = 1
log_ajax_response_write_limit = 300
allow_html_editor_source_button = Off
allow_html_editor_biti_buttons = Off
allow_ctrl_enter_on_compose = Off
try_to_detect_hidden_images = Off
hide_dangerous_actions = Off
use_app_debug_js = Off
use_app_debug_css = Off
use_imap_sort = On
use_imap_force_selection = Off
use_imap_list_subscribe = On
use_imap_thread = On
use_imap_move = On
use_imap_auth_plain = Off
use_imap_expunge_all_on_delete = Off
imap_forwarded_flag = "$Forwarded"
imap_read_receipt_flag = "$ReadReceipt"
imap_body_text_limit = 555000
imap_message_list_fast_simple_search = On
imap_message_list_count_limit_trigger = 0
imap_message_list_date_filter = 0
imap_message_list_permanent_filter = ""
imap_message_all_headers = Off
imap_large_thread_limit = 50
imap_folder_list_limit = 200
imap_show_login_alert = On
smtp_show_server_errors = Off
sieve_allow_raw_script = Off
sieve_utf8_folder_name = On
mail_func_clear_headers = On
mail_func_additional_parameters = Off
favicon_status = On
folders_spec_limit = 50
owncloud_save_folder = "Attachments"
curl_proxy = ""
curl_proxy_auth = ""
in_iframe = Off
force_https = Off
custom_login_link = ""
custom_logout_link = ""
allow_external_login = Off
allow_external_sso = Off
external_sso_key = ""
http_client_ip_check_proxy = Off
fast_cache_memcache_host = "127.0.0.1"
fast_cache_memcache_port = 11211
fast_cache_memcache_expire = 43200
use_local_proxy_for_external_images = Off
cookie_default_path = ""
startup_url = ""
emogrifier = On
dev_email = ""
dev_password = ""
[version]
current = "1.9.3.363"
saved = "Wed, 07 Oct 2015 09:22:24 +0000"

View file

@ -0,0 +1,16 @@
imap_host = "auto"
imap_port = 993
imap_secure = "SSL"
imap_short_login = Off
sieve_use = Off
sieve_allow_raw = Off
sieve_host = ""
sieve_port = 4190
sieve_secure = "None"
smtp_host = "auto"
smtp_port = 465
smtp_secure = "SSL"
smtp_short_login = Off
smtp_auth = On
smtp_php_mail = Off
white_list = ""

View file

@ -0,0 +1,16 @@
imap_host = "localhost"
imap_port = 993
imap_secure = "SSL"
imap_short_login = On
sieve_use = On
sieve_allow_raw = On
sieve_host = "localhost"
sieve_port = 4190
sieve_secure = "TLS"
smtp_host = "localhost"
smtp_port = 587
smtp_secure = "TLS"
smtp_short_login = On
smtp_auth = On
smtp_php_mail = Off
white_list = ""

View file

@ -5,8 +5,16 @@ location PATHTOCHANGE {
rewrite ^ https://$server_name$request_uri? permanent;
}
location ^~ PATHTOCHANGE/app/data {
deny all;
}
location ^~ PATHTOCHANGE/pgpback/keys {
deny all;
}
client_max_body_size 10G;
index index.php;
index index.php index.html;
try_files $uri $uri/ index.php;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;

7
hooks/post_domain_add Normal file
View file

@ -0,0 +1,7 @@
#!/bin/bash
app='rainloop' # This could never work with multi-instance. Need to find a better way
domain=$1
rainloop_path=/var/www/$app/app
sudo cp ../conf/data/domains/domain.tld.ini $rainloop_path/data/_data_/_default_/domains/$domain.ini

7
hooks/post_domain_remove Normal file
View file

@ -0,0 +1,7 @@
#!/bin/bash
app='rainloop' # This could never work with multi-instance. Need to find a better way
domain=$1
rainloop_path=/var/www/$app/app
sudo rm $rainloop_path/data/_data_/_default_/domains/$domain.ini

View file

@ -1,16 +1,25 @@
{
"packaging_format": 1,
"name": "Rainloop",
"id": "rainloop",
"description": {
"en": "Lightweight webmail",
"fr": "Webmail leger"
"en": "Lightweight multi-account webmail",
"fr": "Webmail léger multi-comptes"
},
"url": "http://rainloop.net/",
"license": "free",
"maintainer": {
"name": "polytan02",
"email": "polytan02@mcgva.org"
"name": "scith, Djip007"
},
"multi_instance": "false",
"multi_instance": false,
"services": [
"nginx",
"php5-fpm",
"mysql"
],
"requirements": {
"yunohost": ">= 2.4.0"
},
"arguments": {
"install" : [
{
@ -35,20 +44,37 @@
{
"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"],
"default": "No"
},
{
"name": "dp_pwd",
{
"name": "password",
"type": "password",
"ask": {
"en": "Choose a password for Rainloop MySQL database. Please note that the table and the user will be rainloop (case sensitive - used for carddav)",
"fr": "Choisissez un mot de passe pour la base MySQL de Rainloop. Veuillez noter que la table et l'utilisateur créés seront rainloop (sensible à la casse - utilisé pour carddav)"
"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 ?"
},
"example": "my_strong_password"
"choices": ["Yes", "No"],
"default": "Yes"
},
{
"name": "lang",
"ask": {
"en": "Select default language",
"fr": "Definir la langue par defaut"
},
"choices": ["English", "Francais"],
"default": "English"
}
]
}

31
scripts/backup Normal file
View file

@ -0,0 +1,31 @@
#!/bin/bash
# Exit on command errors and treat unset variables as an error
set -eu
app=$YNH_APP_INSTANCE_NAME
# Set app specific variables
dbname=$app
dbuser=$app
# Source app helpers
source /usr/share/yunohost/helpers
# Retrieve app settings
domain=$(ynh_app_setting_get "$app" domain)
path=$(ynh_app_setting_get "$app" path)
dbpass=$(ynh_app_setting_get "$app" mysqlpwd)
# Copy the app files
DESTDIR="/var/www/$app"
ynh_backup "$DESTDIR" "sources"
# Copy the conf files
ynh_backup "/etc/nginx/conf.d/${domain}.d/${app}.conf" "nginx.conf"
# Copy dedicated php-fpm process to backup folder
ynh_backup "/etc/php5/fpm/pool.d/${app}.conf" "php-fpm.conf"
# Dump the database
mysqldump -u "$dbuser" -p"$dbpass" --no-create-db "$dbname" > ./db.sql
ynh_backup "db.sql" "dump.sql"

View file

@ -1,80 +1,148 @@
#!/bin/bash
app=rainloop
# Exit on command errors and treat unset variables as an error
set -eu
app=$YNH_APP_INSTANCE_NAME
rainloop_version='1.10.5.192'
# Source app helpers
. /usr/share/yunohost/helpers
# Retrieve arguments
domain=$1
path=$2
is_public=$3
# 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
domain=$YNH_APP_ARG_DOMAIN
path=$YNH_APP_ARG_PATH
is_public=$YNH_APP_ARG_IS_PUBLIC
password=$YNH_APP_ARG_PASSWORD
ldap=$YNH_APP_ARG_LDAP
lang=$YNH_APP_ARG_LANG
# Correct path
if [ "${path:0:1}" != "/" ]; then
path="/$path"
fi
if [ "${path:${#path}-1}" == "/" ] && [ ${#path} -gt 1 ]; then
path="${path:0:${#path}-1}"
fi
# Check domain/path availability
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')
db_pwd=$4
sudo yunohost app checkurl "${domain}${path}" -a "$app" \
|| ynh_die "Path not available: ${domain}${path}"
# Use 'rainloop' as database name and user
db_user=$app
dbuser=$app
dbname=$app
dbpass=$(ynh_string_random)
# 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
ynh_mysql_create_db "$dbname" "$dbuser" "$dbpass"
ynh_app_setting_set "$app" mysqlpwd "$dbpass"
#mysql -u $db_user -p$db_pwd $db_user < ../sources/plugins/automatic_addressbook/SQL/mysql.initial.sql
# Create the final path and copy sources
final_path=/var/www/$app
rainloop_path=${final_path}/app
# Copy files to the right place
final_path=/var/www/$app
sudo rm -rf $final_path
sudo mkdir -p $final_path
# Use of latest community edition
sudo wget http://repository.rainloop.net/v2/webmail/rainloop-community-latest.zip -O $final_path/rainloop.zip
sudo unzip $final_path/rainloop.zip -d $final_path/
sudo rm $final_path/rainloop.zip
sudo rm -rf $final_path
sudo mkdir -p $final_path
sudo mkdir -p $rainloop_path
# Download sources and keys
sudo wget -q https://github.com/RainLoop/rainloop-webmail/releases/download/v${rainloop_version}/rainloop-community-${rainloop_version}.zip
sudo wget -q https://github.com/RainLoop/rainloop-webmail/releases/download/v${rainloop_version}/rainloop-community-${rainloop_version}.zip.asc
sudo wget -q https://repository.rainloop.net/RainLoop.asc
# Verify the integrity of sources
sudo gpg --import --quiet RainLoop.asc
sudo gpg --verify --quiet rainloop-community-${rainloop_version}.zip.asc rainloop-community-${rainloop_version}.zip || ynh_die "Download failed"
sudo gpg --batch --delete-key --yes Rainloop
# Unzip
sudo unzip -qq rainloop-community-${rainloop_version}.zip -d $rainloop_path/
# Install plugins
sudo mkdir -p $rainloop_path/data/_data_/_default_/plugins
sudo cp -rf ../sources/plugins/auto-domain-grab $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-suggestions $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
# Set lang => define from install manifest
case "$lang" in
Francais)
lang="fr"
;;
English)
lang="en"
;;
*)
lang="en"
esac
ynh_app_setting_set "$app" lang "$lang"
# Set plugins
plugins="auto-domain-grab" # This plugin is trying to automatically grab unknown domains if users want to add external email accounts
if [ "$ldap" = "Yes" ];
then
plugins="$plugins,ynh-ldap-suggestions" # This plugin is to suggest YunoHost users in recipients list
fi
ynh_app_setting_set "$app" plugins "$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@$dbuser@g" $application_file
sudo sed -i "s@MYSQLPASSWORD@$dbpass@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"
ynh_app_setting_set "$app" 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 ldomain in $alldomains ; do
sudo cp ../conf/data/domains/domain.tld.ini $rainloop_path/data/_data_/_default_/domains/$ldomain.ini
done
# Add wildcard domain for auto-grab
sudo cp ../conf/data/domains/default.ini $rainloop_path/data/_data_/_default_/domains/default.ini
# install SSO - at the moment the index is the SSO and rainloop is installed in /app
sudo cp ../sources/sso/sso.php $final_path/index.php
sudo sed -i "s@domain.tld@$domain@g" $final_path/index.php
sudo sed -i "s@PATHTOCHANGE@$path@g" $final_path/index.php
# Install PGPback by chtixof to allow users to backup/restore their PGP private keys on the server
sudo cp -rf ../sources/pgpback $final_path/.
# Set permissions to rainloop directory
# sudo mkdir -p $final_path/logs
sudo chown -R www-data:www-data $final_path
sudo find $final_path/. -type d -exec chmod 755 {} \;
sudo find $final_path/. -type f -exec chmod 644 {} \;
sudo chown -R www-data:www-data $final_path
# Modify Nginx configuration file and copy it to Nginx conf directory
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
sed -i "s@ALIASTOCHANGE@$final_path/@g" ../conf/nginx.conf
sed -i "s@NAMETOCHANGE@$app@g" ../conf/nginx.conf
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
# 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
sed -i "s@NAMETOCHANGE@$app@g" ../conf/php-fpm.conf
finalphpconf=/etc/php5/fpm/pool.d/$app.conf
sudo cp ../conf/php-fpm.conf $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
ynh_app_setting_set "$app" is_public "$is_public"
if [ "$is_public" = "Yes" ];
then
ynh_app_setting_set "$app" skipped_uris "/"
fi
# Reload Nginx and regenerate SSOwat conf
sudo service php5-fpm reload
sudo service nginx reload
sudo yunohost app ssowatconf
# Reload services
sudo service php5-fpm reload || true
sudo service nginx reload || true

View file

@ -1,18 +1,29 @@
#!/bin/bash
app=rainloop
# Exit on command errors and treat unset variables as an error
set -eu
app=$YNH_APP_INSTANCE_NAME
db_user=$app
db_name=$app
root_pwd=$(sudo cat /etc/yunohost/mysql)
domain=$(sudo yunohost app setting $app domain)
# Source app helpers
source /usr/share/yunohost/helpers
mysql -u root -p$root_pwd -e "DROP DATABASE $db_name ; DROP USER $db_user@localhost ;"
sudo rm -rf /var/www/$app
sudo rm -f /etc/nginx/conf.d/$domain.d/$app.conf
sudo rm -f /etc/php5/fpm/pool.d/$app.conf
# Retrieve arguments
dbuser=$app
dbname=$app
domain=$(ynh_app_setting_get "$app" domain)
sudo service php5-fpm restart
sudo service nginx reload
sudo yunohost app ssowatconf
# Drop MySQL database and user
ynh_mysql_drop_db "$dbname" 2>&1 || true
ynh_mysql_drop_user "$dbuser" 2>&1 || true
# Delete app directory and configurations
sudo rm -rf "/var/www/${app}"
sudo rm -f "/etc/php5/fpm/pool.d/${app}.conf"
[[ -n $domain ]] && sudo rm -f "/etc/nginx/conf.d/${domain}.d/${app}.conf"
# Remove GPG key
sudo gpg --batch --delete-key --yes Rainloop
# Reload services
sudo service php5-fpm reload || true
sudo service nginx reload || true

56
scripts/restore Normal file
View file

@ -0,0 +1,56 @@
#!/bin/bash
# Exit on command errors and treat unset variables as an error
set -eu
# Get multi-instances specific variables
app=$YNH_APP_INSTANCE_NAME
# Source app helpers
source /usr/share/yunohost/helpers
# Retrieve old app settings
domain=$(ynh_app_setting_get "$app" domain)
path=$(ynh_app_setting_get "$app" path)
dbname=$app
dbuser=$app
dbpass=$(ynh_app_setting_get "$app" mysqlpwd)
# Check domain/path availability
sudo yunohost app checkurl "${domain}${path}" -a "$app" \
|| ynh_die
# Check destination directory
DESTDIR="/var/www/$app"
[[ -d $DESTDIR ]] && ynh_die \
"The destination directory '$DESTDIR' already exists.\
You should safely delete it before restoring this app."
# Check configuration files
nginx_conf="/etc/nginx/conf.d/${domain}.d/${app}.conf"
[[ -f $nginx_conf ]] && ynh_die \
"The NGINX configuration already exists at '${nginx_conf}'.
You should safely delete it before restoring this app."
phpfpm_conf="/etc/php5/fpm/pool.d/${app}.conf"
[[ -f $phpfpm_conf ]] && ynh_die \
"The PHP FPM configuration already exists at '${phpfpm_conf}'.
You should safely delete it before restoring this app."
# Restore the app files
sudo cp -a ./sources "$DESTDIR"
# Create and restore the database
ynh_mysql_create_db $dbname $dbuser $dbpass
ynh_mysql_connect_as $dbuser $dbpass $dbname < ./dump.sql
# Fix installation directories and permissions
sudo mkdir -p "${DESTDIR}/logs" "${DESTDIR}/temp"
sudo chown -R www-data: "$DESTDIR"
# Restore configuration files
sudo cp -a ./nginx.conf "$nginx_conf"
sudo cp -a ./php-fpm.conf "$phpfpm_conf"
# Reload services
sudo service php5-fpm reload || true
sudo service nginx reload || true

View file

@ -1,51 +1,99 @@
#!/bin/bash
app=$YNH_APP_INSTANCE_NAME
rainloop_version='1.10.5.192'
app=rainloop
# Backup the current version of the app, restore it if the upgrade fails
# Check if old backup exists
if sudo yunohost backup list | grep -q $app-before-upgrade > /dev/null 2>&1;
then
sudo yunohost backup delete $app-before-upgrade
else
echo "no old backup to delete"
fi
sudo yunohost backup create --ignore-hooks --apps $app --name $app-before-upgrade --quiet
EXIT_PROPERLY () {
trap '' EXIT
set +eu
sudo yunohost backup restore --ignore-hooks $app-before-upgrade --apps $app --force --quiet # Restore the backup if upgrade failed
ynh_die "Upgrade failed. The app was restored to the way it was before the failed upgrade."
}
set -eu
trap EXIT_PROPERLY ERR
# Source app helpers
source /usr/share/yunohost/helpers
# 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 rainloop mysqlpwd)
db_user=$app
domain=$(ynh_app_setting_get "$app" domain)
path=$(ynh_app_setting_get "$app" path)
is_public=$(ynh_app_setting_get "$app" is_public)
password=$(ynh_app_setting_get "$app" password)
ldap=$(ynh_app_setting_get "$app" ldap)
lang=$(ynh_app_setting_get "$app" lang)
dp_pwd=$(ynh_app_setting_get "$app" mysqlpwd)
db_user=$app
plugins=$(ynh_app_setting_get "$app" plugins)
# Initialize database and store mysql password for upgrade
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
# Correct path
if [ "${path:0:1}" != "/" ]; then
path="/$path"
fi
if [ "${path:${#path}-1}" == "/" ] && [ ${#path} -gt 1 ]; then
path="${path:0:${#path}-1}"
fi
# Copy files to the right place
final_path=/var/www/$app
#sudo rm -rf $final_path/*
# Use of latest community edition
sudo wget http://repository.rainloop.net/v2/webmail/rainloop-community-latest.zip -O $final_path/rainloop.zip
sudo unzip -ou $final_path/rainloop.zip -d $final_path/
sudo rm $final_path/rainloop.zip
# no update for db now...
# Copy the new sources
final_path=/var/www/$app
rainloop_path=${final_path}/app
sudo rm -rf $rainloop_path/rainloop # Remove the previous Rainloop files except data
# Download sources and keys
sudo wget -q https://github.com/RainLoop/rainloop-webmail/releases/download/v${rainloop_version}/rainloop-community-${rainloop_version}.zip
sudo wget -q https://github.com/RainLoop/rainloop-webmail/releases/download/v${rainloop_version}/rainloop-community-${rainloop_version}.zip.asc
sudo wget -q https://repository.rainloop.net/RainLoop.asc
# Verify the integrity of sources
sudo gpg --import --quiet RainLoop.asc
sudo gpg --verify --quiet rainloop-community-${rainloop_version}.zip.asc rainloop-community-${rainloop_version}.zip
sudo gpg --batch --delete-key --yes Rainloop
# Unzip and overwrite
sudo unzip -qq -o rainloop-community-${rainloop_version}.zip -d $rainloop_path/
# Update ynh plugins:
sudo mkdir -p $rainloop_path/data/_data_/_default_/plugins
sudo cp -rf ../sources/plugins/auto-domain-grab $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-suggestions $rainloop_path/data/_data_/_default_/plugins/.
# update SSO
sudo cp ../sources/sso/sso.php $final_path/index.php
sudo sed -i "s@domain.tld@$domain@g" $final_path/index.php
sudo sed -i "s@PATHTOCHANGE@$path@g" $final_path/index.php
# Install PGPback by chtixof to allow users to backup/restore their PGP private keys on the server
sudo cp -rf ../sources/pgpback $final_path/.
# Set permissions to rainloop directory
sudo chown -R www-data:www-data /var/www/$app
sudo find $final_path/. -type d -exec chmod 755 {} \;
sudo find $final_path/. -type f -exec chmod 644 {} \;
sudo chown -R www-data:www-data $final_path
# Modify Nginx configuration file and copy it to Nginx conf directory
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
sed -i "s@ALIASTOCHANGE@$final_path/@g" ../conf/nginx.conf
sed -i "s@NAMETOCHANGE@$app@g" ../conf/nginx.conf
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
# 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
sed -i "s@NAMETOCHANGE@$app@g" ../conf/php-fpm.conf
finalphpconf=/etc/php5/fpm/pool.d/$app.conf
sudo cp ../conf/php-fpm.conf $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
# Reload Nginx and regenerate SSOwat conf
sudo service php5-fpm reload
sudo service nginx reload
sudo yunohost app ssowatconf
# Reload services
sudo service php5-fpm reload || true
sudo service nginx reload || true

23
sources/pgpback/fav.php Normal file
View file

@ -0,0 +1,23 @@
<?php
$text=file_get_contents('php://input');
$user=$_SERVER["PHP_AUTH_USER"];
$file='keys/pk_'.$user.'.json';
if ($user=="") {
$out='{"rc":-2,"pk":[]}';
} else if ($text=="") {
$fread=file_get_contents($file);
if ($fread==""){
$out='{"rc":-3,"pk":[]}';
} else {
$out='{"rc":-1,"pk":'.file_get_contents($file).'}';
}
} else {
$fstatus=file_put_contents($file,$text) ;
$out='{"rc":'.$fstatus.',"pk":[]}';
}
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Content-Type: application/json; charset=utf-8");
echo json_encode($out);
?>

View file

@ -0,0 +1,90 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>PGPBack
</title>
<style>
body {
background: #41444f;
color: #bbb;
}
a {
color: #fff;
text-decoration:none;
}
a:hover {
color: #fff;
text-decoration:underline;
}
</style>
</head>
<body>
<h1>PGPBack : OpenPGP keys backup for Rainloop</h1>
PGPBack has been tested with Chrome. It enables the following:<br><br>
<a id="arestorels" href="javascript:void(0)">Set the local OpenPGP keys from the server</a><br/><br/>
<a id="asavels" href="javascript:void(0)">Backup the local OpenPGP keys onto the server</a><br/><br/>
<a id="aclearls" href="javascript:void(0)">Clear the local OpenPGP keys (for security reasons)</a><br/><br/>
<script src="lib/jquery-1.11.2.min.js"></script>
<script>
$(document).ready(function() {
$('#asavels').click(function() {
if (confirm('The local OpenPGP keys will be loaded onto the server')) {
$.ajax("fav.php", {
data : JSON.stringify([localStorage["openpgp-private-keys"],localStorage["openpgp-public-keys"]]),
contentType : 'application/json',
type : 'POST',
dataType: 'json',
success: function (data) {
parseddata=JSON.parse(data);
switch (parseddata.rc){
case -2:
alert("User not logged in Yunohost. Keys not saved.");
break;
case -1:
case -3:
alert("No keys to save.");
break;
case 0:
alert("Problem when writing the data. Keys not saved.");
break;
default:
alert("Keys saved ("+parseddata.rc+" bytes).");
}
}
});
}
});
$('#aclearls').click(function() {
if (confirm('The local OpenPGP keys will be deleted')) {
delete localStorage["openpgp-private-keys"];
delete localStorage["openpgp-public-keys"];
}
});
$('#arestorels').click(function() {
if (confirm('The local OpenPGP keys will be replaced by those from the server')) {
$.ajax("fav.php", {
contentType : 'application/json',
type : 'POST',
dataType: 'json',
success: function (data) {
parseddata=JSON.parse(data);
switch (parseddata.rc){
case -2:
alert("User not logged in Yunohost. Keys not set.");
break;
case -3:
alert("No data found. Keys not set.");
break;
default:
localStorage["openpgp-private-keys"]=parseddata.pk[0];
localStorage["openpgp-public-keys"]=parseddata.pk[1];
alert("Keys set from the server.");
}
}
});
}
});
})
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,27 @@
This plugin, written by https://github.com/jas8522
and optimised by
https://github.com/rhyswilliamsza
https://github.com/rhysit
https://github.com/RainLoop
is released under:
The MIT License (MIT)
Copyright (c) 2015 https://github.com/jas8522
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,14 @@
What is it?
In essense, this plugin allows for multiple users across multiple servers to use one RainLoop installation,
all without the administrator needing to create each domain separately. This plugin detects the required
hostname from the inputted email address (for example, it would detect "example.com" as the hostname if
"info@example.com" is inputted). This hostname is then used for IMAP and SMTP communication.
How to Use:
1) Activate plugin
2) Visit Settings, and add a new wildcard domain "*"
3) Set your ports/ssl requirements as needed. These will not be changed by the plugin.
4) In the SMTP and/or IMAP host fields, place the single word "auto". This will be replaced when the plugin is active.
5) That's it! The plugin should now work!

View file

@ -0,0 +1 @@
1.1

View file

@ -0,0 +1,56 @@
<?php
/**
* This plug-in automatically detects the IMAP and SMTP settings by extracting them from the email address itself.
* For example, user inputs: "info@example.com"
* This plugin sets the IMAP and SMTP host to "example.com" upon login, and then connects to it.
*
* Based on:
* https://github.com/RainLoop/rainloop-webmail/blob/master/plugins/override-smtp-credentials/index.php
*
*/
class AutoDomainGrabPlugin extends \RainLoop\Plugins\AbstractPlugin
{
public function Init()
{
$this->addHook('filter.smtp-credentials', 'FilterSmtpCredentials');
$this->addHook('filter.imap-credentials', 'FilterImapCredentials');
}
/**
* This function detects the IMAP Host, and if it is set to "auto", replaces it with the email domain.
*
* @param \RainLoop\Model\Account $oAccount
* @param array $aImapCredentials
*/
public function FilterImapCredentials($oAccount, &$aImapCredentials)
{
if ($oAccount instanceof \RainLoop\Model\Account && \is_array($aImapCredentials))
{
// Check for mail.$DOMAIN as entered value in RL settings
if (!empty($aImapCredentials['Host']) && 'auto' === $aImapCredentials['Host'])
{
$aImapCredentials['Host'] = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email());
}
}
}
/**
* This function detects the SMTP Host, and if it is set to "auto", replaces it with the email domain.
*
* @param \RainLoop\Model\Account $oAccount
* @param array $aSmtpCredentials
*/
public function FilterSmtpCredentials($oAccount, &$aSmtpCredentials)
{
if ($oAccount instanceof \RainLoop\Model\Account && \is_array($aSmtpCredentials))
{
// Check for mail.$DOMAIN as entered value in RL settings
if (!empty($aSmtpCredentials['Host']) && 'auto' === $aSmtpCredentials['Host'])
{
$aSmtpCredentials['Host'] = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email());
}
}
}
}

View file

@ -0,0 +1 @@
Plugin which allows to suggess email from ynh ldap

View file

@ -0,0 +1 @@
0.1

View file

@ -0,0 +1,170 @@
<?php
class YnhLdapSuggestions implements \RainLoop\Providers\Suggestions\ISuggestions {
/**
*
* @var \MailSo\Log\Logger
*/
private $oLogger = null;
/**
*
* @param \RainLoop\Model\Account $oAccount
* @param string $sQuery
* @param int $iLimit
* = 20
*
* @return array
*/
public function Process($oAccount, $sQuery, $iLimit = 20) {
$sQuery = \trim ( $sQuery );
if ('' === $sQuery || ! $oAccount) {
return array ();
}
$aResult = $this->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 ( 'YnhLdapSuggestions: 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 ( 'YnhLdapSuggestions: 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 ( 'YnhLdapSuggestions: 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 ( 'YnhLdapSuggestions: 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;
}
}
?>

View file

@ -0,0 +1,37 @@
<?php
class YnhLdapSuggestionsPlugin extends \RainLoop\Plugins\AbstractPlugin {
public function Init() {
$this->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__ . '/YnhLdapSuggestions.php';
if (! \is_array ( $mResult )) {
$mResult = array ();
}
$oProvider = new YnhLdapSuggestions ();
$mResult [] = $oProvider;
}
}
}
?>

View file

@ -0,0 +1 @@
Plugin which allows you to get username from ynh ldap by email address

View file

@ -0,0 +1 @@
0.1

View file

@ -0,0 +1,92 @@
<?php
class YnhLoginMappingPlugin extends \RainLoop\Plugins\AbstractPlugin {
public function Init() {
$this->addHook ( 'filter.login-credentials', 'FilterLoginСredentials' );
}
/**
*
* @param string $sEmail
* @param string $sLogin
* @param string $sPassword
*
* @throws \RainLoop\Exceptions\ClientException
*/
public function FilterLoginСredentials(&$sEmail, &$sLogin, &$sPassword) {
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin::FilterLoginСredentials IN => '.$sEmail.'/'.$sLogin, \MailSo\Log\Enumerations\Type::INFO);
// connection au ldap ynh... en local
$cnx = ldap_connect (); // single connection
if (! $cnx) {
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin: Could not connect to LDAP server', \MailSo\Log\Enumerations\Type::ERROR);
return;
}
if (! ldap_bind ( $cnx )) {
// bizard... ca renvoie false.... mais ca marche....
$this->Manager()->Actions()->Logger()->Write('LdapLoginMappingPlugin: Could not bind to LDAP server', \MailSo\Log\Enumerations\Type::ERROR);
// return;
}
// Voir d'abord si le mail est dans un domaine de ynh
// pour ca il faut d'abord recuperer la liste des domaines...
$dn = "ou=domains,dc=yunohost,dc=org";
// on veut tous les virtualdomain... pour un mail donné ??? verifier top...
$filter = "(objectClass=mailDomain)";
$attrs = array( 'virtualdomain');
// OK un petit recherche sur les domaines
$sr = ldap_search( $cnx, $dn, $filter, $attrs );
$domains = ldap_get_entries($cnx, $sr);
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin: ldap_search(domains) => '.var_export($domains, true ), \MailSo\Log\Enumerations\Type::INFO, 'LDAP');
$is_ynh = false;
// @ verifier avec la log du dessus
for($i = 0; $i < $domains['count']; $i ++) {
$domain = '@' . $domains[$i]['virtualdomain'][0];
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin: domains['.$i.'] => '.$domain, \MailSo\Log\Enumerations\Type::INFO, 'LDAP');
if ($this->endsWith($sEmail, $domain)) {
$is_ynh = true;
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin: => OK', \MailSo\Log\Enumerations\Type::INFO, 'LDAP');
}
}
// si le mail n'est pas l'un des domaines de ynh ca ne nous conserne pas... on sort!
if (! $is_ynh) {
return;
}
// on veut mail et uid... pour un mail donné
$dn = "ou=users,dc=yunohost,dc=org";
$filter = "(&(objectClass=inetOrgPerson)(mail=$sEmail))";
$attrs = array('uid', 'mail');
// OK un petit recherche sur les mails...
$sr = ldap_search($cnx, $dn, $filter, $attrs);
if (!$sr) {
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin: search on LDAP server', \MailSo\Log\Enumerations\Type::ERROR);
return;
}
$result = ldap_get_entries ( $cnx, $sr );
$this->Manager ()->Actions ()->Logger ()->Write ( 'YnhLoginMappingPlugin: ldap_search(users) => ' . var_export ( $result, true ), \MailSo\Log\Enumerations\Type::INFO, 'LDAP' );
// OK si on a un resultat on recupere l'identifiant de l'utilisateur...
if (($result['count'] > 0) && ($result[0]['uid']['count'] > 0)) {
$sLogin = $result[0]['uid'][0];
} else {
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin: user not found', \MailSo\Log\Enumerations\Type::ERROR);
}
$this->Manager()->Actions()->Logger()->Write('YnhLoginMappingPlugin::FilterLoginСredentials OUT => '.$sEmail.'/'.$sLogin, \MailSo\Log\Enumerations\Type::INFO);
}
private function beginsWith($str, $sub) {
return (substr ( $str, 0, strlen ( $sub ) ) === $sub);
}
private function endsWith($str, $sub) {
return (substr ( $str, strlen ( $str ) - strlen ( $sub ) ) === $sub);
}
}

35
sources/sso/index.php Normal file
View file

@ -0,0 +1,35 @@
<?php
if (!defined('APP_VERSION')) {
$version = file_get_contents('data/VERSION');
if ($version) {
define('APP_VERSION', $version);
define('APP_INDEX_ROOT_FILE', __FILE__);
define('APP_INDEX_ROOT_PATH', str_replace('\\', '/', rtrim(dirname(__FILE__), '\\/').'/'));
}
}
if(isset($_GET["auto_log"])) {
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
}
if (file_exists(APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php')) {
include APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php';
} else {
echo '[105] Missing version directory';
exit(105);
}
if(isset($_GET["auto_log"])) {
if (isset($_SERVER['HTTP_EMAIL']) && isset($_SERVER['PHP_AUTH_PW'])) {
$email = $_SERVER['HTTP_EMAIL'];
$password = $_SERVER['PHP_AUTH_PW'];
$ssoHash = \RainLoop\Api::GetUserSsoHash($email, $password);
// redirect to webmail sso url
\header('Location: https://domain.tldPATHTOCHANGE/index.php?sso&hash='.$ssoHash);
}
exit();
}
?>

18
sources/sso/sso.php Normal file
View file

@ -0,0 +1,18 @@
<?php
// Enable RainLoop Api and include index file
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
include '/var/www/rainloop/app/index.php';
// Retrieve email and password
if (isset($_SERVER['HTTP_EMAIL']) && isset($_SERVER['PHP_AUTH_PW'])) {
$email = $_SERVER['HTTP_EMAIL'];
$password = $_SERVER['PHP_AUTH_PW'];
$ssoHash = \RainLoop\Api::GetUserSsoHash($email, $password);
// redirect to webmail sso url
\header('Location: https://domain.tldPATHTOCHANGE/app/index.php?sso&hash='.$ssoHash);
}
else {
\header('Location: https://domain.tldPATHTOCHANGE/app/index.php');
}