Browse Source

evoadmin-mail: complete refactoring, use Debian Package

tags/9.7.0^2
Victor Laborie 1 year ago
parent
commit
2a6cb3b381
19 changed files with 62 additions and 402 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +0
    -15
      webapps/evoadmin-mail/defaults/main.yml
  3. +2
    -1
      webapps/evoadmin-mail/files/pool.evoadmin-mail.conf
  4. +2
    -2
      webapps/evoadmin-mail/handlers/main.yml
  5. +13
    -16
      webapps/evoadmin-mail/tasks/apache.yml
  6. +0
    -17
      webapps/evoadmin-mail/tasks/config.yml
  7. +16
    -5
      webapps/evoadmin-mail/tasks/main.yml
  8. +11
    -11
      webapps/evoadmin-mail/tasks/nginx.yml
  9. +0
    -15
      webapps/evoadmin-mail/tasks/packages.yml
  10. +9
    -3
      webapps/evoadmin-mail/tasks/ssl.yml
  11. +0
    -121
      webapps/evoadmin-mail/tasks/user.yml
  12. +6
    -7
      webapps/evoadmin-mail/templates/apache_evoadminmail.conf.j2
  13. +0
    -56
      webapps/evoadmin-mail/templates/conf.php.j2
  14. +0
    -28
      webapps/evoadmin-mail/templates/connect.php.j2
  15. +0
    -12
      webapps/evoadmin-mail/templates/evoadmin.ldif.j2
  16. +2
    -2
      webapps/evoadmin-mail/templates/nginx_evoadminmail.conf.j2
  17. +0
    -3
      webapps/evoadmin-mail/templates/sudoers.j2
  18. +0
    -2
      webapps/evoadmin-mail/templates/web-add.conf.j2
  19. +0
    -86
      webapps/evoadmin-mail/templates/web-mail.tpl.j2

+ 1
- 0
CHANGELOG.md View File

@@ -31,6 +31,7 @@ The **patch** part changes incrementally at each release.
### Changed
* minifirewall: compare config before/after (for restart condition)
* squid: better replacement in minifirewall config
* evoadmin-mail: complete refactoring, use Debian Package

## [9.5.0] - 2018-11-14



+ 0
- 15
webapps/evoadmin-mail/defaults/main.yml View File

@@ -3,22 +3,7 @@ general_alert_email: "root@localhost"
evoadminmail_contact_email: Null
evoadminmail_bounce_email: "{{ evoadminmail_contact_email }}"

evoadminmail_username: evoadmin-mail
evoadminmail_home_dir: "/home/{{ evoadminmail_username }}"
evoadminmail_document_root: "{{ evoadminmail_home_dir }}/www"
evoadminmail_log_dir: "{{ evoadminmail_home_dir }}/log"
evoadminmail_scripts_dir: /usr/share/scripts/
evoadminmail_host: "evoadminmail.{{ ansible_fqdn }}"

evoadminmail_enable_vhost: True
evoadminmail_webserver: apache

evoadminmail_tpl_servername: "{{ ansible_fqdn }}"
evoadminmail_tpl_address: "{{ ansible_default_ipv4.address }}"
evoadminmail_tpl_phpmyadmin_url: Null
evoadminmail_tpl_cgi_suffix: Null
evoadminmail_tpl_signature: evoadmin
evoadminmail_tpl_mail_from: root@localhost
evoadminmail_tpl_mail_bcc: Null
evoadminmail_tpl_mail_standard: "{{ general_alert_email }}"
evoadminmail_tpl_mail_urgent: "{{ general_alert_email }}"

+ 2
- 1
webapps/evoadmin-mail/files/pool.evoadmin-mail.conf View File

@@ -1,6 +1,6 @@
[evoadmin-mail]

user = www-evoadmin-mail
user = evoadmin-mail
group = evoadmin-mail

listen = /run/php/php7.0-evoadmin-mail-fpm.sock
@@ -12,3 +12,4 @@ listen.group = www-data
pm = ondemand
pm.max_children = 25

env[EVOADMINMAIL_CONFIG_FILE] = /etc/evoadmin-mail/config.ini

+ 2
- 2
webapps/evoadmin-mail/handlers/main.yml View File

@@ -11,5 +11,5 @@

- name: reload php-fpm
service:
name: php7.0-fpm
state: reload
name: php7.0-fpm
state: reloaded

+ 13
- 16
webapps/evoadmin-mail/tasks/apache.yml View File

@@ -1,30 +1,27 @@
---

- name: "Set custom values for PHP config (Debian 9 or later)"
ini_file:
dest: /etc/php/7.0/apache2/conf.d/zzz-evolinux-custom.ini
section: PHP
option: "disable_functions"
value: "shell-exec,system,passthru,putenv,popen,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority"
notify: reload apache2
when: ansible_distribution_major_version | version_compare('9', '>=')

- name: Install evoadminmail VHost
template:
src: apache_evoadminmail.conf.j2
dest: /etc/apache2/sites-available/evoadminmail.conf
notify: reload apache2
tags:
- evoadmin-mail

- name: Enable evoadminmail vhost
command: "a2ensite evoadminmail.conf"
register: cmd_a2ensite
changed_when: "'Enabling site' in cmd_a2ensite.stdout"
file:
src: "/etc/apache2/sites-available/evoadminmail.conf"
dest: "/etc/apache2/sites-enabled/evoadminmail.conf"
state: link
notify: reload apache2
when: evoadminmail_enable_vhost
tags:
- evoadmin-mail

- name: Disable evoadminmail vhost
command: "a2dissite evoadminmail.conf"
register: cmd_a2dissite
changed_when: "'Disabling site' in cmd_a2dissite.stdout"
file:
dest: "/etc/apache2/sites-enabled/evoadminmail.conf"
state: absent
notify: reload apache2
when: not evoadminmail_enable_vhost
tags:
- evoadmin-mail

+ 0
- 17
webapps/evoadmin-mail/tasks/config.yml View File

@@ -1,17 +0,0 @@
---

- name: "Create /etc/evolinux"
file:
dest: "/etc/evolinux"
recurse: yes
state: directory

#- name: Configure web-add config file
# template:
# src: web-add.conf.j2
# dest: /etc/evolinux/web-add.conf
#
#- name: Configure web-add template file for mail
# template:
# src: web-mail.tpl.j2
# dest: "{{ evoadminmail_scripts_dir }}/web-mail.tpl"

+ 16
- 5
webapps/evoadmin-mail/tasks/main.yml View File

@@ -1,10 +1,19 @@
---
- name: Install evoadmin-mail package
apt:
name: evoadmin-mail
state: present
tags:
- evoadmin-mail

- include: packages.yml

- include: user.yml

- include: config.yml
- name: Configure contact mail
ini_file:
dest: /etc/evoadmin-mail/config.ini
section: global
option: mail
value: "\"{{ evoadminmail_contact_email or general_alert_email | mandatory }}\""
tags:
- evoadmin-mail

- include: ssl.yml

@@ -21,3 +30,5 @@
regexp: "EvoAdmin-mail"
line: ' <li><a href="https://{{ evoadminmail_host }}">Interface admin mail (EvoAdmin-mail)</a></li>'
insertbefore: "</ul>"
tags:
- evoadmin-mail

+ 11
- 11
webapps/evoadmin-mail/tasks/nginx.yml View File

@@ -1,25 +1,19 @@
---

- name: "Set custom values for PHP config (Debian 9 or later)"
ini_file:
dest: /etc/php/7.0/fpm/conf.d/zzz-evolinux-custom.ini
section: PHP
option: "disable_functions"
value: "shell-exec,system,passthru,putenv,popen,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority"
notify: reload nginx
when: ansible_distribution_major_version | version_compare('9', '>=')

- name: Copy php-fpm evoadmin-mail pool
copy:
src: pool.evoadmin-mail.conf
dest: /etc/php/7.0/fpm/pool.d/evoadmin-mail.conf
notify: reload php-fpm
tags:
- evoadmin-mail

- name: Install evoadminmail VHost
template:
src: nginx_evoadminmail.conf.j2
dest: /etc/nginx/sites-available/evoadminmail.conf
notify: reload nginx
tags:
- evoadmin-mail

- name: Active evoadminmail VHost
file:
@@ -28,8 +22,14 @@
state: link
notify: reload nginx
when: evoadminmail_enable_vhost
tags:
- evoadmin-mail

- name: Disable evoadminmail vhost
command: "unlink /etc/nginx/sites-enabled/evoadminmail.conf"
file:
dest: "/etc/nginx/sites-enabled/evoadminmail.conf"
state: absent
notify: reload nginx
when: not evoadminmail_enable_vhost
tags:
- evoadmin-mail

+ 0
- 15
webapps/evoadmin-mail/tasks/packages.yml View File

@@ -1,15 +0,0 @@
---

- include_role:
name: apt
tasks_from: evolix_public.yml

- name: Install PHP packages
apt:
name: '{{ item }}'
state: present
with_items:
- php-pear
- php-log
- php-crypt-chap
- php-twig

+ 9
- 3
webapps/evoadmin-mail/tasks/ssl.yml View File

@@ -1,24 +1,30 @@
---


- name: ssl-cert package is installed
apt:
name: ssl-cert
state: present
tags:
- evoadmin-mail

- name: Create private key and csr for default site ({{ ansible_fqdn }})
command: openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/{{ evoadminmail_host }}.key -out /etc/ssl/{{ evoadminmail_host }}.csr -batch -subj "/CN={{ evoadminmail_host }}"
args:
creates: "/etc/ssl/private/{{ evoadminmail_host }}.key"
tags:
- evoadmin-mail

- name: Adjust rights on private key
file:
path: /etc/ssl/private/{{ evoadminmail_host }}.key
dest: /etc/ssl/private/{{ evoadminmail_host }}.key
owner: root
group: ssl-cert
mode: "0640"
tags:
- evoadmin-mail

- name: Create certificate for default site
command: openssl x509 -req -days 3650 -sha256 -in /etc/ssl/{{ evoadminmail_host }}.csr -signkey /etc/ssl/private/{{ evoadminmail_host }}.key -out /etc/ssl/certs/{{ evoadminmail_host }}.crt
args:
creates: "/etc/ssl/certs/{{ evoadminmail_host }}.crt"
tags:
- evoadmin-mail

+ 0
- 121
webapps/evoadmin-mail/tasks/user.yml View File

@@ -1,121 +0,0 @@
---

- name: Create evoadmin account
user:
name: "{{ evoadminmail_username }}"
comment: "Evoadmin Web Account"
home: "{{ evoadminmail_home_dir}}"
shell: /bin/bash
password: "!"

- name: Create log/ directory
file:
path: "{{ evoadminmail_home_dir}}/log"
state: directory
owner: "{{ evoadminmail_username }}"
group: "{{ evoadminmail_username }}"
mode: "0750"

- name: Create www-evoadminmail group
group:
name: "www-{{ evoadminmail_username }}"
state: present

- name: "Create www-evoadmin (Debian 9 or later)"
user:
name: "www-{{ evoadminmail_username }}"
home: "{{ evoadminmail_home_dir}}/www"
shell: /bin/bash
createhome: no
when: ansible_distribution_major_version | version_compare('9', '>=')

- name: Add www-data to app's group
user:
name: 'www-data'
groups: "{{ evoadminmail_username }}"
append: yes
when: evoadminmail_webserver == "nginx"

- name: Install Git
apt:
name: git
state: present

- name: "Clone evoadmin repository (Debian 9 or later)"
git:
repo: https://forge.evolix.org/evoadmin-mail.git
dest: "{{ evoadminmail_document_root}}"
version: master
update: yes
when: ansible_distribution_major_version | version_compare('9', '>=')

- name: "Change perms on evoadminmail document root"
file:
dest: "{{ evoadminmail_document_root }}"
owner: "www-{{ evoadminmail_username }}"
group: "{{ evoadminmail_username }}"
recurse: yes

- name: "Copy connect.php"
template:
src: connect.php.j2
dest: "{{ evoadminmail_document_root }}/htdocs/config/connect.php"
owner: "www-{{ evoadminmail_username }}"
group: "{{ evoadminmail_username }}"
when: ldap_admin_password is defined

- name: "Copy conf.php"
template:
src: conf.php.j2
dest: "{{ evoadminmail_document_root }}/htdocs/config/conf.php"
owner: "www-{{ evoadminmail_username }}"
group: "{{ evoadminmail_username }}"

- name: create a password for evoadmin user
command: "apg -n 1 -m 16 -M lcN"
register: evoadminmail_admin_password
changed_when: False

- name: upload ldif for evoadmin user
template:
src: evoadmin.ldif.j2
dest: /root/evolinux_evoadminmail_admin.ldif
mode: "0640"

- name: inject config
command: slapadd -l /root/evolinux_evoadminmail_admin.ldif

- name: create log file
file:
dest: /var/log/evoadmin-mail.log
state: touch
owner: "www-{{ evoadminmail_username }}"
group: "adm"
mode: "0640"

- include_role:
name: remount-usr
when: evoadminmail_scripts_dir | search ("/usr")

- name: "Create {{ evoadminmail_scripts_dir }}"
file:
dest: "{{ evoadminmail_scripts_dir }}"
# recurse: yes
mode: "0700"
state: directory

# we use a shell command to have a "changed" thet really reflects the result.
- name: Fix permissions
shell: "chmod -R --verbose u=rwX,g=rX,o= {{ item }}"
register: command_result
changed_when: "'changed' in command_result.stdout"
# failed_when: False
with_items:
- "{{ evoadminmail_home_dir}}/www"

#- name: Add evoadmin sudoers file
# template:
# src: sudoers.j2
# dest: /etc/sudoers.d/evoadmin
# mode: "0600"
# validate: "visudo -cf %s"

+ 6
- 7
webapps/evoadmin-mail/templates/apache_evoadminmail.conf.j2 View File

@@ -10,7 +10,7 @@
#ServerAlias {{ evoadminmail_host }}

# Repertoire principal
DocumentRoot {{ evoadminmail_document_root }}/htdocs/
DocumentRoot /usr/share/evoadmin-mail/

# SSL
SSLEngine on
@@ -19,7 +19,7 @@
SSLProtocol all -SSLv2 -SSLv3

# Propriete du repertoire
<Directory {{ evoadminmail_document_root }}/htdocs/>
<Directory /usr/share/evoadmin-mail/>
#Options Indexes SymLinksIfOwnerMatch
Options SymLinksIfOwnerMatch
AllowOverride AuthConfig Limit FileInfo Indexes
@@ -27,15 +27,15 @@
</Directory>

# user - group (thanks to sesse@debian.org)
AssignUserID www-{{ evoadminmail_username }} {{ evoadminmail_username }}
AssignUserID evoadmin-mail evoadmin-mail

# LOG
CustomLog /var/log/apache2/access.log combined
CustomLog {{ evoadminmail_log_dir }}/access.log combined
ErrorLog {{ evoadminmail_log_dir }}/error.log
ErrorLog /var/log/apache2/error.log

# AWSTATS
SetEnv AWSTATS_FORCE_CONFIG {{ evoadminmail_username }}
SetEnv AWSTATS_FORCE_CONFIG evoadmin-mail
SetEnv EVOADMINMAIL_CONFIG_FILE /etc/evoadmin-mail/config.ini

# REWRITE
UseCanonicalName On
@@ -53,6 +53,5 @@
#php_admin_value max_execution_time 60
#php_admin_value upload_max_filesize 8M
#php_admin_flag allow_url_fopen Off
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f www-{{ evoadminmail_username }}"
php_admin_value open_basedir "none"
</VirtualHost>

+ 0
- 56
webapps/evoadmin-mail/templates/conf.php.j2 View File

@@ -1,56 +0,0 @@
<?php

// Email pour les notifications
$conf['admin']['mail'] = '{{ evoadminmail_contact_email or general_alert_email | mandatory }}';
// login des superadmins
// Note: utile uniquement si domaines/driver=ldap, laisser vide sinon...
$conf['admin']['logins'] = array('evoadmin');
// What do you want?
// 0 = nothing...
// 1 = only mail accounts
// 2 = only samba accounts
// 3 = mail and samba accounts
$conf['admin']['what'] = 1;
// use hook.php instead of hook-dist.php
$conf['admin']['use_hook'] = false;
// enable quota
$conf['admin']['quota'] = true;

// compatibilite LDAP
$conf['evoadmin']['version'] = 3;
$conf['url']['webroot'] = '/';

$conf['domaines']['onlyone'] = false;
$conf['domaines']['driver'] = 'ldap';
$conf['domaines']['file']['all'] = array('example.com');
$conf['domaines']['file']['gid'] = 1000;
// Pack Mail "virtuel"... attention
// uniquement possible si $conf['admin']['what']=1 !!
$conf['domaines']['ldap']['virtual'] = true;

// Mode cluster
// Uniquement en mode mail seul et des utilisateurs virtuels
$conf['evoadmin']['cluster'] = false;

// auth SMTP by default ?
$conf['evoadmin']['useauthsmtp'] = false;

// Si comptes virtuels
$conf['unix']['uid'] = 5000;

// Si pas virtuel
$conf['unix']['minuid'] = 1000;
$conf['unix']['mingid'] = 1000;

$conf['html']['title'] = "Evoadmin Mail";

// gestion des logs
$conf['log']['priority'] = PEAR_LOG_DEBUG;
$conf['log']['name'] = '/var/log/evoadmin-mail.log';
$conf['log']['software'] = 'evoadminmail';
$conf['log']['enabled'] = true;

// samba
$conf['samba']['dn'] = 'DOMAINNAME';
$conf['samba']['sid'] = 'S-1-5-21-XXX-XXX-XXX';
$conf['samba']['admin_default'] = false;

+ 0
- 28
webapps/evoadmin-mail/templates/connect.php.j2 View File

@@ -1,28 +0,0 @@
<?php

/**
* Secrete parameters
*
* $Id: connect-dist.php,v 1.3 2007-05-22 21:12:23 reg Exp $
*
* @author Gregory Colpart <reg@evolix.fr>
* @version 1.0
*/

define("LDAP_URI","ldap://127.0.0.1");
$ldap_servers = array('ldap://127.0.0.1');
define("LDAP_BASE","{{ ldap_suffix }}");
define("LDAP_ADMIN_DN","cn=admin,{{ ldap_suffix }}");
define("LDAP_ADMIN_PASS","{{ ldap_admin_password.stdout }}");

define("SUDOBIN","/usr/bin/sudo");
define("SUDOSCRIPT","/usr/share/scripts/evoadmin.sh");
define("SUDOPASS","xxxxxx");

define('SERVEUR','localhost');
define('SERVEURPORT',3306);
define('BASE','horde');
define('NOM', 'horde');
define('PASSE', 'xxxx');

?>

+ 0
- 12
webapps/evoadmin-mail/templates/evoadmin.ldif.j2 View File

@@ -1,12 +0,0 @@
dn: uid=evoadmin,{{ ldap_suffix }}
uid: evoadmin
cn: Evoadmin ADM
uidNumber: 4242
gidNumber: 4242
homeDirectory: /dev/null
isAdmin: TRUE
mailacceptinggeneralid: evoadmin@{{ ansible_fqdn }}
objectClass: mailAccount
objectClass: organizationalRole
objectClass: posixAccount
userPassword: {{ evoadminmail_admin_password.stdout }}

+ 2
- 2
webapps/evoadmin-mail/templates/nginx_evoadminmail.conf.j2 View File

@@ -18,10 +18,10 @@ server {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root {{ evoadminmail_document_root }}/htdocs/;
root /usr/share/evoadmin-mail/;
location / {
index index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {


+ 0
- 3
webapps/evoadmin-mail/templates/sudoers.j2 View File

@@ -1,3 +0,0 @@
User_Alias EVOADMIN = www-evoadmin
Cmnd_Alias EVOADMIN_WEB = {{ evoadmin_scripts_dir | mandatory }}/web-*.sh, {{ evoadmin_scripts_dir | mandatory }}/ftpadmin.sh
EVOADMIN ALL=NOPASSWD: EVOADMIN_WEB

+ 0
- 2
webapps/evoadmin-mail/templates/web-add.conf.j2 View File

@@ -1,2 +0,0 @@
CONTACT_MAIL="{{ evoadmin_contact_email or general_alert_email | mandatory }}"
WWWBOUNCE_MAIL="{{ evoadmin_bounce_email or general_alert_email | mandatory }}"

+ 0
- 86
webapps/evoadmin-mail/templates/web-mail.tpl.j2 View File

@@ -1,86 +0,0 @@
From: {{ evoadmin_tpl_mail_from }}
To: RCPTTO
Bcc: {{ evoadmin_tpl_mail_bcc }}
Subject: Parametres hebergement web : LOGIN

Bonjour,

Votre compte d'hebergement web a ete cree.

**********************************
* CONNEXION SFTP/SSH
**********************************

NOM DU SERVEUR : {{ evoadmin_tpl_servername }}
USER : LOGIN
PASSWORD : PASSE1

*****************************************
* Details sur l'environnement Apache/PHP
*****************************************

URL du site :
http://{{ evoadmin_tpl_servername }}

URL des stats :
http://{{ evoadmin_tpl_servername }}/cgi-RANDOM/awstats.pl
(acces par IP ou login a demander !)

Repertoire de connexion : HOME_DIR/LOGIN/
Repertoire pour site web : HOME_DIR/LOGIN/www/

Apache/PHP tourne en www-LOGIN:LOGIN c'est-a-dire qu'il a acces
uniquement *en lecture* aux differents fichiers/repertoires
(a condition d'avoir 'g=rx' sur les repertoires et 'g=r' sur les
fichiers ce qui est le comportement par defaut).

Lorsqu'on a besoin d'autoriser *l'ecriture* pour certains
fichiers/repertoires, il suffit d'ajouter le droit 'g+w'.

***********************************
* MySQL
***********************************

SERVEUR : 127.0.0.1
PORT DU SERVEUR : 3306
USER : LOGIN
PASSWORD : PASSE2
NOM BASE : DBNAME
URL interface d'admin :
{{ evoadmin_tpl_phpmyadmin_url }}

***********************************
* Rappels divers
***********************************

Votre nom de domaine doit etre configure pour pointer
sur l'adresse IP {{ evoadmin_tpl_address }} (enregistrement DNS A)
ou etre un alias de {{ evoadmin_tpl_servername }} (enregistrement DNS CNAME).

Si vous avez besoin de faire des tests, vous devez
ajouter la ligne suivante au fichier "/etc/hosts" sous Linux/Unix
ou au fichier "system32\drivers\etc\hosts" sous Windows NT/XP :
{{ evoadmin_tpl_address }} {{ evoadmin_tpl_servername }}

Attention, par defaut, toutes les connexions vers l'exterieur
sont bloquees. Si vous avez besoin de recuperer des donnees
a l'exterieur (flux RSS, BDD externe, etc.), contactez nous
afin de mettre en oeuvre les autorisations necessaires.

Afin de securiser au maximum le serveur, certaines URL
particulieres sont non autorisees pour eviter diverses
attaques (XSS, robots, trojans, injections, etc.).
Exemple d'URL refusee :
http://{{ evoadmin_tpl_servername }}/cmd32.exe
En cas de soucis avec votre application, prevenez-nous.

Si vous desirez mettre en place des parametres particuliers
pour votre site (PHP, etc.) ou pour tout autre demande (scripts en crontab,
etc.), n'hesitez pas a nous contacter a l'adresse
{{ evoadmin_tpl_mail_standard }} (ou {{ evoadmin_tpl_mail_urgent }} si votre demande est
urgente).


Cordialement,
--
{{ evoadmin_tpl_signature }}

Loading…
Cancel
Save