first commit
22
dockers/apikaz/Readme.txt
Normal file
@ -0,0 +1,22 @@
|
||||
yo, ceci est l'api de kaz !
|
||||
|
||||
https://apikaz.kazkouil.fr/
|
||||
|
||||
Je pars de ça: python api + docker-compose: https://dev.to/alissonzampietro/the-amazing-journey-of-docker-compose-17lj
|
||||
|
||||
Pour la doc:
|
||||
module Flask + flask-restful + flasgger
|
||||
https://stackoverflow.com/questions/75840827/how-to-properly-generate-a-documentation-with-swagger-for-flask
|
||||
https://medium.com/@DanKaranja/building-api-documentation-in-flask-with-swagger-a-step-by-step-guide-59a453509e2f
|
||||
https://apidog.com/blog/what-is-flasgger/
|
||||
|
||||
autre piste: abandonnée pour l'instant. trop jeune ?
|
||||
Documentation (OpenApi remplace swagger)
|
||||
https://pypi.org/project/flask-openapi3/
|
||||
|
||||
|
||||
TODO:
|
||||
* sécurisation de l'API : un token ? otp ?
|
||||
* sécurité: comment différencier les rôles admin (tout faire) et kaznaute (changer uniquement ses coordonnées, relancer son site propre web, ...)
|
||||
* pourquoi pas une seule classe pour plusieurs api ? (par exemple LDAP, pas mal de factorisation possible)
|
||||
* pourquoi pas de donnée dans le body ? (au lieu des variables dans l'url). par ex, pour le message du mail.
|
56
dockers/apikaz/docker-compose.yml
Normal file
@ -0,0 +1,56 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
api-service:
|
||||
build: ./source/
|
||||
container_name: ${apikazServName}
|
||||
# restart: ${restartPolicy}
|
||||
volumes:
|
||||
- ./source/:/usr/src/app/
|
||||
#pour être dans la même time zone que le host
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- 5000:5000
|
||||
env_file:
|
||||
- ../../secret/env-${apikazServName}
|
||||
environment:
|
||||
PORT: 5000
|
||||
FLASK_DEBUG: 1
|
||||
FLASK_ENV: development # Activation du rechargement automatique
|
||||
#important sinon mmctl va aller taper sur PROD1
|
||||
ENV MMCTL_SERVER: "https://${apikazHost}.${domain}"
|
||||
# volumes:
|
||||
# - apiKaz:/
|
||||
networks:
|
||||
- apikazNet
|
||||
- pahekoNet
|
||||
- ldapNet
|
||||
- cloudNet
|
||||
- postfixNet
|
||||
external_links:
|
||||
- ${smtpServName}:${smtpHost}.${domain}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${apikazServName}.rule=Host(`${apikazHost}.${domain}`)"
|
||||
- "traefik.http.routers.${apikazServName}.middlewares=test-adminipwhitelist@file"
|
||||
- "traefik.docker.network=apikazNet"
|
||||
|
||||
#volumes:
|
||||
# apiKaz:
|
||||
|
||||
networks:
|
||||
apikazNet:
|
||||
external: true
|
||||
name: apikazNet
|
||||
pahekoNet:
|
||||
external: true
|
||||
name: pahekoNet
|
||||
ldapNet:
|
||||
external: true
|
||||
name: ldapNet
|
||||
cloudNet:
|
||||
external: true
|
||||
name: cloudNet
|
||||
postfixNet:
|
||||
external: true
|
||||
name: postfixNet
|
31
dockers/apikaz/source/Dockerfile
Normal file
@ -0,0 +1,31 @@
|
||||
FROM python:3.11
|
||||
|
||||
#cette image permet d'avoir l'env python ainsi que le mode "reload on change", pratique quand on modifie les sources *.py
|
||||
|
||||
# maj des packages dispo
|
||||
RUN apt-get update
|
||||
|
||||
#ldap pour le pip install python-ldap car apt-get python-ldap marche po
|
||||
RUN apt-get install -y libsasl2-dev python3-dev libldap2-dev libssl-dev ldap-utils
|
||||
|
||||
#pour l'api soap sympa', perl est déjà installé mais il faut les modules suivant
|
||||
RUN cpan App::cpanminus
|
||||
RUN cpanm SOAP::Lite XML::LibXML MIME::EncWords Text::LineFold Class::Singleton Locale::Messages
|
||||
|
||||
#installer le truc de génération de mot de mdp
|
||||
RUN apt-get -y install apg
|
||||
|
||||
#installer mmctl pour mattermost
|
||||
RUN mkdir -p /mm/ && cd /mm/ && \
|
||||
curl -vfsSL -O https://releases.mattermost.com/mmctl/v9.7.1/linux_amd64.tar && \
|
||||
tar -xf linux_amd64.tar
|
||||
|
||||
#l'api Kaz
|
||||
RUN mkdir /usr/src/app/
|
||||
COPY . /usr/src/app/
|
||||
WORKDIR /usr/src/app/
|
||||
EXPOSE 5000
|
||||
|
||||
#les modules python à installer lors du build
|
||||
RUN pip install -r requirements.txt
|
||||
CMD ["python", "app.py"]
|
75
dockers/apikaz/source/Sympa/Constants.pm
Normal file
@ -0,0 +1,75 @@
|
||||
# -*- indent-tabs-mode: nil; -*-
|
||||
# vim:ft=perl:et:sw=4
|
||||
# $Id$
|
||||
|
||||
# Sympa - SYsteme de Multi-Postage Automatique
|
||||
#
|
||||
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
|
||||
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
|
||||
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
|
||||
# Copyright 2018 The Sympa Community. See the AUTHORS.md file at the
|
||||
# top-level directory of this distribution and at
|
||||
# <https://github.com/sympa-community/sympa.git>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package Sympa::Constants;
|
||||
|
||||
use strict;
|
||||
|
||||
use constant VERSION => '--VERSION--';
|
||||
use constant USER => '--USER--';
|
||||
use constant GROUP => '--GROUP--';
|
||||
|
||||
use constant CONFIG => '--CONFIG--';
|
||||
use constant WWSCONFIG => '--WWSCONFIG--';
|
||||
use constant SENDMAIL_ALIASES => '--SENDMAIL_ALIASES--';
|
||||
|
||||
use constant PIDDIR => '--piddir--';
|
||||
use constant EXPLDIR => '--expldir--';
|
||||
use constant SPOOLDIR => '--spooldir--';
|
||||
use constant SYSCONFDIR => '--sysconfdir--';
|
||||
use constant LOCALEDIR => '--localedir--';
|
||||
use constant LIBEXECDIR => '--libexecdir--';
|
||||
use constant SBINDIR => '--sbindir--';
|
||||
use constant SCRIPTDIR => '--scriptdir--';
|
||||
use constant MODULEDIR => '--modulesdir--';
|
||||
use constant DEFAULTDIR => '--defaultdir--';
|
||||
use constant ARCDIR => '--arcdir--';
|
||||
use constant BOUNCEDIR => '--bouncedir--';
|
||||
use constant EXECCGIDIR => '--execcgidir--';
|
||||
use constant STATICDIR => '--staticdir--';
|
||||
use constant CSSDIR => '--cssdir--';
|
||||
use constant PICTURESDIR => '--picturesdir--';
|
||||
|
||||
use constant EMAIL_LEN => 100;
|
||||
use constant FAMILY_LEN => 50;
|
||||
use constant LIST_LEN => 50;
|
||||
use constant ROBOT_LEN => 80;
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sympa::Constants - Definition of constants
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module keeps definition of constants used by Sympa software.
|
||||
|
||||
=cut
|
1225
dockers/apikaz/source/Sympa/Language.pm
Normal file
128
dockers/apikaz/source/Sympa/Regexps.pm
Normal file
@ -0,0 +1,128 @@
|
||||
# -*- indent-tabs-mode: nil; -*-
|
||||
# vim:ft=perl:et:sw=4
|
||||
|
||||
# Sympa - SYsteme de Multi-Postage Automatique
|
||||
#
|
||||
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
|
||||
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
|
||||
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
|
||||
# Copyright 2017, 2021, 2022, 2023 The Sympa Community. See the
|
||||
# AUTHORS.md file at the top-level directory of this distribution and at
|
||||
# <https://github.com/sympa-community/sympa.git>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package Sympa::Regexps;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# domain name.
|
||||
use constant domain => qr'[-\w]+(?:[.][-\w]+)+';
|
||||
|
||||
# These are relaxed variants of the syntax for mailbox described in RFC 5322.
|
||||
# See also RFC 5322, 3.2.3 & 3.4.1 for details on format.
|
||||
use constant email =>
|
||||
qr{(?:[A-Za-z0-9!\#\$%\&'*+\-/=?^_`{|}~.]+|"(?:\\.|[^\\"])*")\@[-\w]+(?:[.][-\w]+)+};
|
||||
|
||||
# This is older definition used by 6.2.65b and earlier.
|
||||
#use constant addrspec => qr{(?:[-&+'./\w=]+|".*")\@[-\w]+(?:[.][-\w]+)+};
|
||||
|
||||
# This is the same as above except that it gave some groups, then regexp
|
||||
# using it should also be changed. By this reason it has been deprecated.
|
||||
#use constant email => qr'([\w\-\_\.\/\+\=\'\&]+|\".*\")\@[\w\-]+(\.[\w\-]+)+';
|
||||
|
||||
use constant family_name => qr'[a-z0-9][a-z0-9\-\.\+_]*';
|
||||
## Allow \s for template names
|
||||
use constant template_name => qr'[a-zA-Z0-9][a-zA-Z0-9\-\.\+_\s]*';
|
||||
#FIXME: Not matching with IPv6 address.
|
||||
use constant host => qr'[\w\.\-]+';
|
||||
use constant hostport => qr{(?:
|
||||
[-.\w]+ (?::\d+)?
|
||||
| [:0-9a-f]*:[:0-9a-f]*:[:0-9a-f]*
|
||||
| \[ [:0-9a-f]*:[:0-9a-f]*:[:0-9a-f]* \] (?::\d+)?
|
||||
)}ix;
|
||||
use constant html_date =>
|
||||
qr'[0-9]{4}[0-9]*-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])';
|
||||
use constant ipv6 => qr'[:0-9a-f]*:[:0-9a-f]*:[:0-9a-f]*'i;
|
||||
#FIXME: Cannot contain IPv6 address.
|
||||
use constant multiple_host_with_port =>
|
||||
'[\w\.\-]+(:\d+)?(,[\w\.\-]+(:\d+)?)*';
|
||||
#FIXME: Cannot contain IPv6 address.
|
||||
use constant multiple_host_or_url =>
|
||||
qr'([-\w]+://.+|[-.\w]+(:\d+)?)(,([-\w]+://.+|[-.\w]+(:\d+)?))*';
|
||||
use constant listname => qr'[a-z0-9][a-z0-9\-\.\+_]*';
|
||||
|
||||
use constant ldap_attrdesc => qr'\w[-\w]*(?:;[-\w]+)*'; # RFC2251, 4.1.5
|
||||
|
||||
# "value" defined in RFC 2045, 5.1.
|
||||
use constant rfc2045_parameter_value =>
|
||||
qr'[^\s\x00-\x1F\x7F-\xFF()<>\@,;:\\/\[\]?=\"]+';
|
||||
|
||||
use constant sql_query => qr'(SELECT|select).*';
|
||||
|
||||
# "scenario" was deprecated. Use "scenario_name".
|
||||
# "scenario_config" is used for compatibility to earlier list config files.
|
||||
use constant scenario_config => qr'[-.,\w]+';
|
||||
use constant scenario_name => qr'[-.\w]+';
|
||||
|
||||
use constant task => qr'\w+';
|
||||
use constant datasource => qr'[\w-]+';
|
||||
use constant uid => qr'[\w\-\.\+]+';
|
||||
use constant time => qr'[012]?[0-9](?:\:[0-5][0-9])?';
|
||||
use constant time_range => __PACKAGE__->time . '-' . __PACKAGE__->time;
|
||||
use constant time_ranges => time_range() . '(?:\s+' . time_range() . ')*';
|
||||
|
||||
use constant re => qr{
|
||||
(?:
|
||||
Antw # Dutch
|
||||
| ATB # Welsh
|
||||
| ATB \. # Latvian
|
||||
| AW # German
|
||||
| Odp # Polish
|
||||
| R # Italian
|
||||
| Re (?: \s* \( \d+ \) | \s* \[ \d+ \] | \*{1,2} \d+ | \^ \d+ )?
|
||||
| REF # French
|
||||
| RES # Portuguese
|
||||
| Rif # Italian
|
||||
| SV # Scandinavian
|
||||
| V\x{00E1} # Magyar, "VA"
|
||||
| VS # Finnish
|
||||
| YNT # Turkish
|
||||
| \x{05D4}\x{05E9}\x{05D1} # Hebrew, "hashev"
|
||||
| \x{0391}\x{03A0} # Greek, "AP"
|
||||
| \x{03A3}\x{03A7}\x{0395}\x{03A4} # Greek, "SChET"
|
||||
| \x{041D}\x{0410} # some Slavic in Cyrillic, "na"
|
||||
| \x{56DE}\x{590D} # Simp. Chinese, "huifu"
|
||||
| \x{56DE}\x{8986} # Trad. Chinese, "huifu"
|
||||
)
|
||||
\s* [:\x{FF1A}]
|
||||
}ix;
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sympa::Regexps - Definition of regular expressions
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module keeps definition of regular expressions used by Sympa software.
|
||||
|
||||
=cut
|
506
dockers/apikaz/source/Sympa/Tools/Data.pm
Normal file
@ -0,0 +1,506 @@
|
||||
# -*- indent-tabs-mode: nil; -*-
|
||||
# vim:ft=perl:et:sw=4
|
||||
# $Id$
|
||||
|
||||
# Sympa - SYsteme de Multi-Postage Automatique
|
||||
#
|
||||
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
|
||||
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
|
||||
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
|
||||
# Copyright 2018 The Sympa Community. See the AUTHORS.md file at the
|
||||
# top-level directory of this distribution and at
|
||||
# <https://github.com/sympa-community/sympa.git>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package Sympa::Tools::Data;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Encode qw();
|
||||
use English qw(-no_match_vars);
|
||||
use POSIX qw();
|
||||
use XML::LibXML qw();
|
||||
BEGIN { eval 'use Clone qw()'; }
|
||||
|
||||
use Sympa::Tools::Text;
|
||||
|
||||
## This applies recursively to a data structure
|
||||
## The transformation subroutine is passed as a ref
|
||||
sub recursive_transformation {
|
||||
my ($var, $subref) = @_;
|
||||
|
||||
return unless (ref($var));
|
||||
|
||||
if (ref($var) eq 'ARRAY') {
|
||||
foreach my $index (0 .. $#{$var}) {
|
||||
if (ref($var->[$index])) {
|
||||
recursive_transformation($var->[$index], $subref);
|
||||
} else {
|
||||
$var->[$index] = &{$subref}($var->[$index]);
|
||||
}
|
||||
}
|
||||
} elsif (ref($var) eq 'HASH') {
|
||||
foreach my $key (keys %{$var}) {
|
||||
if (ref($var->{$key})) {
|
||||
recursive_transformation($var->{$key}, $subref);
|
||||
} else {
|
||||
$var->{$key} = &{$subref}($var->{$key});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
## Dump a variable's content
|
||||
sub dump_var {
|
||||
my ($var, $level, $fd) = @_;
|
||||
|
||||
return undef unless ($fd);
|
||||
|
||||
if (ref($var)) {
|
||||
if (ref($var) eq 'ARRAY') {
|
||||
foreach my $index (0 .. $#{$var}) {
|
||||
print $fd "\t" x $level . $index . "\n";
|
||||
dump_var($var->[$index], $level + 1, $fd);
|
||||
}
|
||||
} elsif (ref($var) eq 'HASH'
|
||||
|| ref($var) eq 'Sympa::Scenario'
|
||||
|| ref($var) eq 'Sympa::List'
|
||||
|| ref($var) eq 'CGI::Fast') {
|
||||
foreach my $key (sort keys %{$var}) {
|
||||
print $fd "\t" x $level . '_' . $key . '_' . "\n";
|
||||
dump_var($var->{$key}, $level + 1, $fd);
|
||||
}
|
||||
} else {
|
||||
printf $fd "\t" x $level . "'%s'" . "\n", ref($var);
|
||||
}
|
||||
} else {
|
||||
if (defined $var) {
|
||||
print $fd "\t" x $level . "'$var'" . "\n";
|
||||
} else {
|
||||
print $fd "\t" x $level . "UNDEF\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Dump a variable's content
|
||||
sub dump_html_var {
|
||||
my ($var) = shift;
|
||||
my $html = '';
|
||||
|
||||
if (ref($var)) {
|
||||
|
||||
if (ref($var) eq 'ARRAY') {
|
||||
$html .= '<ul>';
|
||||
foreach my $index (0 .. $#{$var}) {
|
||||
$html .= '<li> ' . $index . ':';
|
||||
$html .= dump_html_var($var->[$index]);
|
||||
$html .= '</li>';
|
||||
}
|
||||
$html .= '</ul>';
|
||||
} elsif (ref($var) eq 'HASH'
|
||||
|| ref($var) eq 'Sympa::Scenario'
|
||||
|| ref($var) eq 'Sympa::List') {
|
||||
$html .= '<ul>';
|
||||
foreach my $key (sort keys %{$var}) {
|
||||
$html .= '<li>' . $key . '=';
|
||||
$html .= dump_html_var($var->{$key});
|
||||
$html .= '</li>';
|
||||
}
|
||||
$html .= '</ul>';
|
||||
} else {
|
||||
$html .= 'EEEEEEEEEEEEEEEEEEEEE' . ref($var);
|
||||
}
|
||||
} else {
|
||||
if (defined $var) {
|
||||
$html .= Sympa::Tools::Text::encode_html($var);
|
||||
} else {
|
||||
$html .= 'UNDEF';
|
||||
}
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
# Duplicates a complex variable (faster).
|
||||
# CAUTION: This duplicates blessed elements even if they are
|
||||
# singleton/multiton; this breaks subroutine references.
|
||||
sub clone_var {
|
||||
return Clone::clone($_[0]) if $Clone::VERSION;
|
||||
goto &dup_var; # '&' needed
|
||||
}
|
||||
|
||||
## Duplictate a complex variable
|
||||
sub dup_var {
|
||||
my ($var) = @_;
|
||||
|
||||
if (ref($var)) {
|
||||
if (ref($var) eq 'ARRAY') {
|
||||
my $new_var = [];
|
||||
foreach my $index (0 .. $#{$var}) {
|
||||
$new_var->[$index] = dup_var($var->[$index]);
|
||||
}
|
||||
return $new_var;
|
||||
} elsif (ref($var) eq 'HASH') {
|
||||
my $new_var = {};
|
||||
foreach my $key (sort keys %{$var}) {
|
||||
$new_var->{$key} = dup_var($var->{$key});
|
||||
}
|
||||
return $new_var;
|
||||
}
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# get_array_from_splitted_string
|
||||
####################################################
|
||||
# return an array made on a string splited by ','.
|
||||
# It removes spaces.
|
||||
#
|
||||
#
|
||||
# IN : -$string (+): string to split
|
||||
#
|
||||
# OUT : -ref(ARRAY)
|
||||
#
|
||||
######################################################
|
||||
# Note: This is used only by Sympa::List.
|
||||
sub get_array_from_splitted_string {
|
||||
my ($string) = @_;
|
||||
my @array;
|
||||
|
||||
foreach my $word (split /,/, $string) {
|
||||
$word =~ s/^\s+//;
|
||||
$word =~ s/\s+$//;
|
||||
push @array, $word;
|
||||
}
|
||||
|
||||
return \@array;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# diff_on_arrays
|
||||
####################################################
|
||||
# Makes set operation on arrays (seen as set, with no double) :
|
||||
# - deleted : A \ B
|
||||
# - added : B \ A
|
||||
# - intersection : A /\ B
|
||||
# - union : A \/ B
|
||||
#
|
||||
# IN : -$setA : ref(ARRAY) - set
|
||||
# -$setB : ref(ARRAY) - set
|
||||
#
|
||||
# OUT : -ref(HASH) with keys :
|
||||
# deleted, added, intersection, union
|
||||
#
|
||||
#######################################################
|
||||
sub diff_on_arrays {
|
||||
my ($setA, $setB) = @_;
|
||||
my $result = {
|
||||
'intersection' => [],
|
||||
'union' => [],
|
||||
'added' => [],
|
||||
'deleted' => []
|
||||
};
|
||||
my %deleted;
|
||||
my %added;
|
||||
my %intersection;
|
||||
my %union;
|
||||
|
||||
my %hashA;
|
||||
my %hashB;
|
||||
|
||||
foreach my $eltA (@$setA) {
|
||||
$hashA{$eltA} = 1;
|
||||
$deleted{$eltA} = 1;
|
||||
$union{$eltA} = 1;
|
||||
}
|
||||
|
||||
foreach my $eltB (@$setB) {
|
||||
$hashB{$eltB} = 1;
|
||||
$added{$eltB} = 1;
|
||||
|
||||
if ($hashA{$eltB}) {
|
||||
$intersection{$eltB} = 1;
|
||||
$deleted{$eltB} = 0;
|
||||
} else {
|
||||
$union{$eltB} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $eltA (@$setA) {
|
||||
if ($hashB{$eltA}) {
|
||||
$added{$eltA} = 0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $elt (keys %deleted) {
|
||||
next unless $elt;
|
||||
push @{$result->{'deleted'}}, $elt if ($deleted{$elt});
|
||||
}
|
||||
foreach my $elt (keys %added) {
|
||||
next unless $elt;
|
||||
push @{$result->{'added'}}, $elt if ($added{$elt});
|
||||
}
|
||||
foreach my $elt (keys %intersection) {
|
||||
next unless $elt;
|
||||
push @{$result->{'intersection'}}, $elt if ($intersection{$elt});
|
||||
}
|
||||
foreach my $elt (keys %union) {
|
||||
next unless $elt;
|
||||
push @{$result->{'union'}}, $elt if ($union{$elt});
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
####################################################
|
||||
# is_in_array
|
||||
####################################################
|
||||
# Test if a value is on an array
|
||||
#
|
||||
# IN : -$setA : ref(ARRAY) - set
|
||||
# -$value : a serached value
|
||||
#
|
||||
# OUT : boolean
|
||||
#######################################################
|
||||
sub is_in_array {
|
||||
my $set = shift;
|
||||
die 'missing parameter "$value"' unless @_;
|
||||
my $value = shift;
|
||||
|
||||
if (defined $value) {
|
||||
foreach my $elt (@{$set || []}) {
|
||||
next unless defined $elt;
|
||||
return 1 if $elt eq $value;
|
||||
}
|
||||
} else {
|
||||
foreach my $elt (@{$set || []}) {
|
||||
return 1 unless defined $elt;
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
=over
|
||||
|
||||
=item smart_eq ( $a, $b )
|
||||
|
||||
I<Function>.
|
||||
Check if two strings are identical.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item $a, $b
|
||||
|
||||
Operands.
|
||||
|
||||
If both of them are undefined, they are equal.
|
||||
If only one of them is undefined, the are not equal.
|
||||
If C<$b> is a L<Regexp> object and it matches to C<$a>, they are equal.
|
||||
Otherwise, they are compared as strings.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
If arguments matched, true value. Otherwise false value.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub smart_eq {
|
||||
die 'missing argument' if scalar @_ < 2;
|
||||
my ($a, $b) = @_;
|
||||
|
||||
if (defined $a and defined $b) {
|
||||
if (ref $b eq 'Regexp') {
|
||||
return 1 if $a =~ $b;
|
||||
} else {
|
||||
return 1 if $a eq $b;
|
||||
}
|
||||
} elsif (!defined $a and !defined $b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
## convert a string formated as var1="value1";var2="value2"; into a hash.
|
||||
## Used when extracting from session table some session properties or when
|
||||
## extracting users preference from user table
|
||||
## Current encoding is NOT compatible with encoding of values with '"'
|
||||
##
|
||||
sub string_2_hash {
|
||||
my $data = shift;
|
||||
my %hash;
|
||||
|
||||
pos($data) = 0;
|
||||
while ($data =~ /\G;?(\w+)\=\"((\\[\"\\]|[^\"])*)\"(?=(;|\z))/g) {
|
||||
my ($var, $val) = ($1, $2);
|
||||
$val =~ s/\\([\"\\])/$1/g;
|
||||
$hash{$var} = $val;
|
||||
}
|
||||
|
||||
return (%hash);
|
||||
|
||||
}
|
||||
## convert a hash into a string formated as var1="value1";var2="value2"; into
|
||||
## a hash
|
||||
sub hash_2_string {
|
||||
my $refhash = shift;
|
||||
|
||||
return undef unless ref $refhash eq 'HASH';
|
||||
|
||||
my $data_string;
|
||||
foreach my $var (keys %$refhash) {
|
||||
next unless length $var;
|
||||
my $val = $refhash->{$var};
|
||||
$val = '' unless defined $val;
|
||||
|
||||
$val =~ s/([\"\\])/\\$1/g;
|
||||
$data_string .= ';' . $var . '="' . $val . '"';
|
||||
}
|
||||
return ($data_string);
|
||||
}
|
||||
|
||||
## compare 2 scalars, string/numeric independant
|
||||
sub smart_lessthan {
|
||||
my ($stra, $strb) = @_;
|
||||
$stra =~ s/^\s+//;
|
||||
$stra =~ s/\s+$//;
|
||||
$strb =~ s/^\s+//;
|
||||
$strb =~ s/\s+$//;
|
||||
$ERRNO = 0;
|
||||
my ($numa, $unparsed) = POSIX::strtod($stra);
|
||||
my $numb;
|
||||
$numb = POSIX::strtod($strb)
|
||||
unless ($ERRNO || $unparsed != 0);
|
||||
|
||||
if (($stra eq '') || ($strb eq '') || ($unparsed != 0) || $ERRNO) {
|
||||
return $stra lt $strb;
|
||||
} else {
|
||||
return $stra < $strb;
|
||||
}
|
||||
}
|
||||
|
||||
=over
|
||||
|
||||
=item sort_uniq ( [ \&comp ], @items )
|
||||
|
||||
Returns sorted array of unique elements in the list.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item \&comp
|
||||
|
||||
Optional subroutine reference to compare each pairs of elements.
|
||||
It should take two arguments and return negative, zero or positive result.
|
||||
|
||||
=item @items
|
||||
|
||||
Items to be sorted.
|
||||
|
||||
=back
|
||||
|
||||
This function was added on Sympa 6.2.16.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub sort_uniq {
|
||||
my $comp;
|
||||
if (ref $_[0] eq 'CODE') {
|
||||
$comp = shift;
|
||||
}
|
||||
|
||||
my %items;
|
||||
@items{@_} = ();
|
||||
|
||||
if ($comp) {
|
||||
return sort { $comp->($a, $b) } keys %items;
|
||||
} else {
|
||||
return sort keys %items;
|
||||
}
|
||||
}
|
||||
|
||||
# Create a custom attribute from an XML description
|
||||
# IN : A string, XML formed data as stored in database
|
||||
# OUT : HASH data storing custome attributes.
|
||||
# Old name: Sympa::List::parseCustomAttribute().
|
||||
sub decode_custom_attribute {
|
||||
my $xmldoc = shift;
|
||||
return undef unless defined $xmldoc and length $xmldoc;
|
||||
|
||||
my $parser = XML::LibXML->new();
|
||||
my $tree;
|
||||
|
||||
## We should use eval to parse to prevent the program to crash if it fails
|
||||
if (ref($xmldoc) eq 'GLOB') {
|
||||
$tree = eval { $parser->parse_fh($xmldoc) };
|
||||
} else {
|
||||
$tree = eval { $parser->parse_string($xmldoc) };
|
||||
}
|
||||
|
||||
return undef unless defined $tree;
|
||||
|
||||
my $doc = $tree->getDocumentElement;
|
||||
|
||||
my @custom_attr = $doc->getChildrenByTagName('custom_attribute');
|
||||
my %ca;
|
||||
foreach my $ca (@custom_attr) {
|
||||
my $id = Encode::encode_utf8($ca->getAttribute('id'));
|
||||
my $value = Encode::encode_utf8($ca->getElementsByTagName('value'));
|
||||
$ca{$id} = {value => $value};
|
||||
}
|
||||
return \%ca;
|
||||
}
|
||||
|
||||
# Create an XML Custom attribute to be stored into data base.
|
||||
# IN : HASH data storing custome attributes
|
||||
# OUT : string, XML formed data to be stored in database
|
||||
# Old name: Sympa::List::createXMLCustomAttribute().
|
||||
sub encode_custom_attribute {
|
||||
my $custom_attr = shift;
|
||||
return
|
||||
'<?xml version="1.0" encoding="UTF-8" ?><custom_attributes></custom_attributes>'
|
||||
if (not defined $custom_attr);
|
||||
my $XMLstr = '<?xml version="1.0" encoding="UTF-8" ?><custom_attributes>';
|
||||
foreach my $k (sort keys %{$custom_attr}) {
|
||||
my $value = $custom_attr->{$k}{value};
|
||||
$value = '' unless defined $value;
|
||||
|
||||
$XMLstr .=
|
||||
"<custom_attribute id=\"$k\"><value>"
|
||||
. Sympa::Tools::Text::encode_html($value, '\000-\037')
|
||||
. "</value></custom_attribute>";
|
||||
}
|
||||
$XMLstr .= "</custom_attributes>";
|
||||
$XMLstr =~ s/\s*\n\s*/ /g;
|
||||
|
||||
return $XMLstr;
|
||||
}
|
||||
|
||||
1;
|
942
dockers/apikaz/source/Sympa/Tools/Text.pm
Normal file
@ -0,0 +1,942 @@
|
||||
# -*- indent-tabs-mode: nil; -*-
|
||||
# vim:ft=perl:et:sw=4
|
||||
# $Id$
|
||||
|
||||
# Sympa - SYsteme de Multi-Postage Automatique
|
||||
#
|
||||
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
|
||||
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
|
||||
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
|
||||
# Copyright 2018, 2020 The Sympa Community. See the AUTHORS.md
|
||||
# file at the top-level directory of this distribution and at
|
||||
# <https://github.com/sympa-community/sympa.git>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package Sympa::Tools::Text;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Encode qw();
|
||||
use English qw(-no_match_vars);
|
||||
use Encode::MIME::Header; # 'MIME-Q' encoding.
|
||||
use HTML::Entities qw();
|
||||
use MIME::EncWords;
|
||||
use Text::LineFold;
|
||||
use Unicode::GCString;
|
||||
use URI::Escape qw();
|
||||
use if ($] < 5.016), qw(Unicode::CaseFold fc);
|
||||
use if (5.016 <= $]), qw(feature fc);
|
||||
BEGIN { eval 'use Unicode::Normalize qw()'; }
|
||||
BEGIN { eval 'use Unicode::UTF8 qw()'; }
|
||||
|
||||
use Sympa::Language;
|
||||
use Sympa::Regexps;
|
||||
|
||||
# Old name: tools::addrencode().
|
||||
sub addrencode {
|
||||
my $addr = shift;
|
||||
my $phrase = (shift || '');
|
||||
my $charset = (shift || 'utf8');
|
||||
my $comment = (shift || '');
|
||||
|
||||
return undef unless $addr =~ /\S/;
|
||||
|
||||
if ($phrase =~ /[^\s\x21-\x7E]/) {
|
||||
$phrase = MIME::EncWords::encode_mimewords(
|
||||
Encode::decode('utf8', $phrase),
|
||||
'Encoding' => 'A',
|
||||
'Charset' => $charset,
|
||||
'Replacement' => 'FALLBACK',
|
||||
'Field' => 'Resent-Sender', # almost longest
|
||||
'Minimal' => 'DISPNAME', # needs MIME::EncWords >= 1.012.
|
||||
);
|
||||
} elsif ($phrase =~ /\S/) {
|
||||
$phrase =~ s/([\\\"])/\\$1/g;
|
||||
$phrase = '"' . $phrase . '"';
|
||||
}
|
||||
if ($comment =~ /[^\s\x21-\x27\x2A-\x5B\x5D-\x7E]/) {
|
||||
$comment = MIME::EncWords::encode_mimewords(
|
||||
Encode::decode('utf8', $comment),
|
||||
'Encoding' => 'A',
|
||||
'Charset' => $charset,
|
||||
'Replacement' => 'FALLBACK',
|
||||
'Minimal' => 'DISPNAME',
|
||||
);
|
||||
} elsif ($comment =~ /\S/) {
|
||||
$comment =~ s/([\\\"])/\\$1/g;
|
||||
}
|
||||
|
||||
return
|
||||
($phrase =~ /\S/ ? "$phrase " : '')
|
||||
. ($comment =~ /\S/ ? "($comment) " : '')
|
||||
. "<$addr>";
|
||||
}
|
||||
|
||||
# Old names: tools::clean_email(), tools::get_canonical_email().
|
||||
sub canonic_email {
|
||||
my $email = shift;
|
||||
|
||||
return undef unless defined $email;
|
||||
|
||||
# Remove leading and trailing white spaces.
|
||||
$email =~ s/\A\s+//;
|
||||
$email =~ s/\s+\z//;
|
||||
|
||||
# Lower-case.
|
||||
$email =~ tr/A-Z/a-z/;
|
||||
|
||||
return (length $email) ? $email : undef;
|
||||
}
|
||||
|
||||
# Old name: tools::clean_msg_id().
|
||||
sub canonic_message_id {
|
||||
my $msg_id = shift;
|
||||
|
||||
return $msg_id unless defined $msg_id;
|
||||
|
||||
chomp $msg_id;
|
||||
|
||||
if ($msg_id =~ /\<(.+)\>/) {
|
||||
$msg_id = $1;
|
||||
}
|
||||
|
||||
return $msg_id;
|
||||
}
|
||||
|
||||
sub canonic_text {
|
||||
my $text = shift;
|
||||
|
||||
return undef unless defined $text;
|
||||
|
||||
# Normalize text. See also discussion on
|
||||
# https://listes.renater.fr/sympa/arc/sympa-developpers/2018-03/thrd1.html
|
||||
#
|
||||
# N.B.: Corresponding modules are optional by now, and should be
|
||||
# mandatory in the future.
|
||||
my $utext;
|
||||
if (Encode::is_utf8($text)) {
|
||||
$utext = $text;
|
||||
} elsif ($Unicode::UTF8::VERSION) {
|
||||
no warnings 'utf8';
|
||||
$utext = Unicode::UTF8::decode_utf8($text);
|
||||
} else {
|
||||
$utext = Encode::decode_utf8($text);
|
||||
}
|
||||
if ($Unicode::Normalize::VERSION) {
|
||||
$utext = Unicode::Normalize::normalize('NFC', $utext);
|
||||
}
|
||||
|
||||
# Remove DOS linefeeds (^M) that cause problems with Outlook 98, AOL,
|
||||
# and EIMS:
|
||||
$utext =~ s/\r\n|\r/\n/g;
|
||||
|
||||
if (Encode::is_utf8($text)) {
|
||||
return $utext;
|
||||
} else {
|
||||
return Encode::encode_utf8($utext);
|
||||
}
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my $path = shift;
|
||||
|
||||
my $ifh;
|
||||
return undef unless open $ifh, '<', $path;
|
||||
my $text = do { local $RS; <$ifh> };
|
||||
close $ifh;
|
||||
|
||||
return canonic_text($text);
|
||||
}
|
||||
|
||||
sub wrap_text {
|
||||
my $text = shift;
|
||||
my $init = shift;
|
||||
my $subs = shift;
|
||||
my $cols = shift;
|
||||
|
||||
$init //= '';
|
||||
$subs //= '';
|
||||
$cols //= 78;
|
||||
return $text unless $cols;
|
||||
|
||||
my $email_re = Sympa::Regexps::email();
|
||||
my $linefold = Text::LineFold->new(
|
||||
Language => Sympa::Language->instance->get_lang,
|
||||
Prep => 'NONBREAKURI',
|
||||
prep => [$email_re, sub { shift; @_ }],
|
||||
ColumnsMax => $cols,
|
||||
Format => sub {
|
||||
shift;
|
||||
my $event = shift;
|
||||
my $str = shift;
|
||||
if ($event =~ /^eo/) { return "\n"; }
|
||||
if ($event =~ /^so[tp]/) { return $init . $str; }
|
||||
if ($event eq 'sol') { return $subs . $str; }
|
||||
undef;
|
||||
},
|
||||
);
|
||||
|
||||
my $t = Encode::is_utf8($text) ? $text : Encode::decode_utf8($text);
|
||||
|
||||
my $ret = '';
|
||||
while (1000 < length $t) {
|
||||
my $s = substr $t, 0, 1000;
|
||||
$ret .= $linefold->break_partial($s);
|
||||
$t = substr $t, 1000;
|
||||
}
|
||||
$ret .= $linefold->break_partial($t) if length $t;
|
||||
$ret .= $linefold->break_partial(undef);
|
||||
|
||||
return Encode::is_utf8($text) ? $ret : Encode::encode_utf8($ret);
|
||||
}
|
||||
|
||||
sub decode_filesystem_safe {
|
||||
my $str = shift;
|
||||
return '' unless defined $str and length $str;
|
||||
|
||||
$str = Encode::encode_utf8($str) if Encode::is_utf8($str);
|
||||
# On case-insensitive filesystem "_XX" along with "_xx" should be decoded.
|
||||
$str =~ s/_([0-9A-Fa-f]{2})/chr hex "0x$1"/eg;
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub decode_html {
|
||||
my $str = shift;
|
||||
|
||||
Encode::encode_utf8(
|
||||
HTML::Entities::decode_entities(Encode::decode_utf8($str)));
|
||||
}
|
||||
|
||||
sub encode_filesystem_safe {
|
||||
my $str = shift;
|
||||
return '' unless defined $str and length $str;
|
||||
|
||||
$str = Encode::encode_utf8($str) if Encode::is_utf8($str);
|
||||
$str =~ s/([^-+.0-9\@A-Za-z])/sprintf '_%02x', ord $1/eg;
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub encode_html {
|
||||
my $str = shift;
|
||||
my $additional_unsafe = shift || '';
|
||||
|
||||
HTML::Entities::encode_entities($str, '<>&"' . $additional_unsafe);
|
||||
}
|
||||
|
||||
sub encode_uri {
|
||||
my $str = shift;
|
||||
my %options = @_;
|
||||
|
||||
# Note: URI-1.35 (URI::Escape 3.28) or later is required.
|
||||
return Encode::encode_utf8(
|
||||
URI::Escape::uri_escape_utf8(
|
||||
Encode::decode_utf8($str),
|
||||
'^-A-Za-z0-9._~' . (exists $options{omit} ? $options{omit} : '')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
# Old name: tools::escape_chars().
|
||||
sub escape_chars {
|
||||
my $s = shift;
|
||||
my $except = shift; ## Exceptions
|
||||
my $ord_except = ord $except if defined $except;
|
||||
|
||||
## Escape chars
|
||||
## !"#$%&'()+,:;<=>?[] AND accented chars
|
||||
## escape % first
|
||||
foreach my $i (
|
||||
0x25,
|
||||
0x20 .. 0x24,
|
||||
0x26 .. 0x2c,
|
||||
0x3a .. 0x3f,
|
||||
0x5b, 0x5d,
|
||||
0x80 .. 0x9f,
|
||||
0xa0 .. 0xff
|
||||
) {
|
||||
next if defined $ord_except and $i == $ord_except;
|
||||
my $hex_i = sprintf "%lx", $i;
|
||||
$s =~ s/\x$hex_i/%$hex_i/g;
|
||||
}
|
||||
## Special traetment for '/'
|
||||
$s =~ s/\//%a5/g unless defined $except and $except eq '/';
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
# Old name: tt2::escape_url().
|
||||
# DEPRECATED. Use Sympa::Tools::Text::escape_uri() or
|
||||
# Sympa::Tools::Text::mailtourl().
|
||||
#sub escape_url;
|
||||
|
||||
sub foldcase {
|
||||
my $str = shift;
|
||||
|
||||
return '' unless defined $str and length $str;
|
||||
# Perl 5.16.0 and later have built-in fc(). Earlier uses Unicode::CaseFold.
|
||||
return Encode::encode_utf8(fc(Encode::decode_utf8($str)));
|
||||
}
|
||||
|
||||
my %legacy_charsets = (
|
||||
'ar' => [qw(iso-8859-6)],
|
||||
'bs' => [qw(iso-8859-2)],
|
||||
'cs' => [qw(iso-8859-2)],
|
||||
'eo' => [qw(iso-8859-3)],
|
||||
'et' => [qw(iso-8859-4)],
|
||||
'he' => [qw(iso-8859-8)],
|
||||
'hr' => [qw(iso-8859-2)],
|
||||
'hu' => [qw(iso-8859-2)],
|
||||
'ja' => [qw(euc-jp cp932 MacJapanese)],
|
||||
'kl' => [qw(iso-8859-4)],
|
||||
'ko' => [qw(cp949)],
|
||||
'lt' => [qw(iso-8859-4)],
|
||||
'lv' => [qw(iso-8859-4)],
|
||||
'mt' => [qw(iso-8859-3)],
|
||||
'pl' => [qw(iso-8859-2)],
|
||||
'ro' => [qw(iso-8859-2)],
|
||||
'ru' => [qw(koi8-r cp1251)], # cp866? MacCyrillic?
|
||||
'sk' => [qw(iso-8859-2)],
|
||||
'sl' => [qw(iso-8859-2)],
|
||||
'th' => [qw(iso-8859-11 cp874 MacThai)],
|
||||
'tr' => [qw(iso-8859-9)],
|
||||
'uk' => [qw(koi8-u)], # MacUkrainian?
|
||||
'zh-CN' => [qw(euc-cn)],
|
||||
'zh-TW' => [qw(big5-eten)],
|
||||
);
|
||||
|
||||
sub guessed_to_utf8 {
|
||||
my $text = shift;
|
||||
my @langs = @_;
|
||||
|
||||
return Encode::encode_utf8($text) if Encode::is_utf8($text);
|
||||
return $text
|
||||
unless defined $text
|
||||
and length $text
|
||||
and $text =~ /[^\x00-\x7F]/;
|
||||
|
||||
my $utf8;
|
||||
if ($Unicode::UTF8::VERSION) {
|
||||
$utf8 =
|
||||
eval { Unicode::UTF8::decode_utf8($text, Encode::FB_CROAK()) };
|
||||
}
|
||||
unless (defined $utf8) {
|
||||
foreach my $charset (map { $_ ? @$_ : () } @legacy_charsets{@langs}) {
|
||||
$utf8 =
|
||||
eval { Encode::decode($charset, $text, Encode::FB_CROAK()) };
|
||||
last if defined $utf8;
|
||||
}
|
||||
}
|
||||
unless (defined $utf8) {
|
||||
$utf8 = Encode::decode('iso-8859-1', $text);
|
||||
}
|
||||
|
||||
# Apply NFC: e.g. for modified-NFD by Mac OS X.
|
||||
$utf8 = Unicode::Normalize::normalize('NFC', $utf8)
|
||||
if $Unicode::Normalize::VERSION;
|
||||
|
||||
return Encode::encode_utf8($utf8);
|
||||
}
|
||||
|
||||
sub mailtourl {
|
||||
my $text = shift;
|
||||
my %options = @_;
|
||||
|
||||
my $dtext =
|
||||
(not defined $text) ? ''
|
||||
: $options{decode_html} ? Sympa::Tools::Text::decode_html($text)
|
||||
: $text;
|
||||
$dtext =~ s/\A\s+//;
|
||||
$dtext =~ s/\s+\z//;
|
||||
$dtext =~ s/(?:\r\n|\r|\n)(?=[ \t])//g;
|
||||
$dtext =~ s/\r\n|\r|\n/ /g;
|
||||
|
||||
# The ``@'' in email address should not be encoded because some MUAs
|
||||
# aren't able to decode ``%40'' in e-mail address of mailto: URL.
|
||||
# Contrary, ``@'' in query component should be encoded because some
|
||||
# MUAs take it for a delimiter to separate URL from the rest.
|
||||
my ($format, $utext, $qsep);
|
||||
if ($dtext =~ /[()<>\[\]:;,\"\s]/) {
|
||||
# Use "to" header if source text includes any of RFC 5322
|
||||
# "specials", minus ``@'' and ``\'', plus whitespaces.
|
||||
$format = 'mailto:?to=%s%s';
|
||||
$utext = Sympa::Tools::Text::encode_uri($dtext);
|
||||
$qsep = '&';
|
||||
} else {
|
||||
$format = 'mailto:%s%s';
|
||||
$utext = Sympa::Tools::Text::encode_uri($dtext, omit => '@');
|
||||
$qsep = '?';
|
||||
}
|
||||
my $qstring = _url_query_string(
|
||||
$options{query},
|
||||
decode_html => $options{decode_html},
|
||||
leadchar => $qsep,
|
||||
sepchar => '&',
|
||||
trim_values => 1,
|
||||
);
|
||||
|
||||
return sprintf $format, $utext, $qstring;
|
||||
}
|
||||
|
||||
sub _url_query_string {
|
||||
my $query = shift;
|
||||
my %options = @_;
|
||||
|
||||
unless (ref $query eq 'HASH' and %$query) {
|
||||
return '';
|
||||
} else {
|
||||
my $decode_html = $options{decode_html};
|
||||
my $trim_values = $options{trim_values};
|
||||
return ($options{leadchar} || '?') . join(
|
||||
($options{sepchar} || ';'),
|
||||
map {
|
||||
my ($dkey, $dval) = map {
|
||||
(not defined $_) ? ''
|
||||
: $decode_html ? Sympa::Tools::Text::decode_html($_)
|
||||
: $_;
|
||||
} ($_, $query->{$_});
|
||||
if ($trim_values and lc $dkey ne 'body') {
|
||||
$dval =~ s/\A\s+//;
|
||||
$dval =~ s/\s+\z//;
|
||||
$dval =~ s/(?:\r\n|\r|\n)(?=[ \t])//g;
|
||||
$dval =~ s/\r\n|\r|\n/ /g;
|
||||
}
|
||||
|
||||
sprintf '%s=%s',
|
||||
Sympa::Tools::Text::encode_uri($dkey),
|
||||
Sympa::Tools::Text::encode_uri($dval);
|
||||
} sort keys %$query
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sub pad {
|
||||
my $str = shift;
|
||||
my $width = shift;
|
||||
|
||||
return $str unless $width and defined $str;
|
||||
|
||||
my $ustr = Encode::is_utf8($str) ? $str : Encode::decode_utf8($str);
|
||||
my $cols = Unicode::GCString->new($ustr)->columns;
|
||||
|
||||
unless ($cols < abs $width) {
|
||||
return $str;
|
||||
} elsif ($width < 0) {
|
||||
return $str . (' ' x (-$width - $cols));
|
||||
} else {
|
||||
return (' ' x ($width - $cols)) . $str;
|
||||
}
|
||||
}
|
||||
|
||||
# Old name: tools::qdecode_filename().
|
||||
sub qdecode_filename {
|
||||
my $filename = shift;
|
||||
|
||||
## We don't use MIME::Words here because it does not encode properly
|
||||
## Unicode
|
||||
## Check if string is already Q-encoded first
|
||||
#if ($filename =~ /\=\?UTF-8\?/) {
|
||||
$filename = Encode::encode_utf8(Encode::decode('MIME-Q', $filename));
|
||||
#}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
# Old name: tools::qencode_filename().
|
||||
sub qencode_filename {
|
||||
my $filename = shift;
|
||||
|
||||
## We don't use MIME::Words here because it does not encode properly
|
||||
## Unicode
|
||||
## Check if string is already Q-encoded first
|
||||
## Also check if the string contains 8bit chars
|
||||
unless ($filename =~ /\=\?UTF-8\?/
|
||||
|| $filename =~ /^[\x00-\x7f]*$/) {
|
||||
|
||||
## Don't encode elements such as .desc. or .url or .moderate
|
||||
## or .extension
|
||||
my $part = $filename;
|
||||
my ($leading, $trailing);
|
||||
$leading = $1 if ($part =~ s/^(\.desc\.)//); ## leading .desc
|
||||
$trailing = $1 if ($part =~ s/((\.\w+)+)$//); ## trailing .xx
|
||||
|
||||
my $encoded_part = MIME::EncWords::encode_mimewords(
|
||||
$part,
|
||||
Charset => 'utf8',
|
||||
Encoding => 'q',
|
||||
MaxLineLen => 1000,
|
||||
Minimal => 'NO'
|
||||
);
|
||||
|
||||
$filename = $leading . $encoded_part . $trailing;
|
||||
}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
# Old name: tools::unescape_chars().
|
||||
sub unescape_chars {
|
||||
my $s = shift;
|
||||
|
||||
$s =~ s/%a5/\//g; ## Special traetment for '/'
|
||||
foreach my $i (0x20 .. 0x2c, 0x3a .. 0x3f, 0x5b, 0x5d, 0x80 .. 0x9f,
|
||||
0xa0 .. 0xff) {
|
||||
my $hex_i = sprintf "%lx", $i;
|
||||
my $hex_s = sprintf "%c", $i;
|
||||
$s =~ s/%$hex_i/$hex_s/g;
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
# Old name: tools::valid_email().
|
||||
sub valid_email {
|
||||
my $email = shift;
|
||||
|
||||
my $email_re = Sympa::Regexps::email();
|
||||
return undef unless $email =~ /^${email_re}$/;
|
||||
|
||||
# Forbidden characters.
|
||||
return undef if $email =~ /[\|\$\*\?\!]/;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub weburl {
|
||||
my $base = shift;
|
||||
my $paths = shift;
|
||||
my %options = @_;
|
||||
|
||||
my @paths = map {
|
||||
Sympa::Tools::Text::encode_uri(
|
||||
(not defined $_) ? ''
|
||||
: $options{decode_html} ? Sympa::Tools::Text::decode_html($_)
|
||||
: $_
|
||||
);
|
||||
} @{$paths || []};
|
||||
|
||||
my $qstring = _url_query_string(
|
||||
$options{query},
|
||||
decode_html => $options{decode_html},
|
||||
sepchar => '&',
|
||||
);
|
||||
|
||||
my $fstring;
|
||||
my $fragment = $options{fragment};
|
||||
if (defined $fragment) {
|
||||
$fstring = '#'
|
||||
. Sympa::Tools::Text::encode_uri(
|
||||
$options{decode_html}
|
||||
? Sympa::Tools::Text::decode_html($fragment)
|
||||
: $fragment
|
||||
);
|
||||
} else {
|
||||
$fstring = '';
|
||||
}
|
||||
|
||||
return sprintf '%s%s%s', join('/', grep { defined $_ } ($base, @paths)),
|
||||
$qstring, $fstring;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sympa::Tools::Text - Text-related functions
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This package provides some text-related functions.
|
||||
|
||||
=head2 Functions
|
||||
|
||||
=over
|
||||
|
||||
=item addrencode ( $addr, [ $phrase, [ $charset, [ $comment ] ] ] )
|
||||
|
||||
Returns formatted (and encoded) name-addr as RFC5322 3.4.
|
||||
|
||||
=item canonic_email ( $email )
|
||||
|
||||
I<Function>.
|
||||
Returns canonical form of e-mail address.
|
||||
|
||||
Leading and trailing white spaces are removed.
|
||||
Latin letters without accents are lower-cased.
|
||||
|
||||
For malformed inputs returns C<undef>.
|
||||
|
||||
=item canonic_message_id ( $message_id )
|
||||
|
||||
Returns canonical form of message ID without trailing or leading whitespaces
|
||||
or C<E<lt>>, C<E<gt>>.
|
||||
|
||||
=item canonic_text ( $text )
|
||||
|
||||
Canonicalizes text.
|
||||
C<$text> should be a binary string encoded by UTF-8 character set or
|
||||
a Unicode string.
|
||||
Forbidden sequences in binary string will be replaced by
|
||||
U+FFFD REPLACEMENT CHARACTERs, and Normalization Form C (NFC) will be applied.
|
||||
|
||||
=item decode_filesystem_safe ( $str )
|
||||
|
||||
I<Function>.
|
||||
Decodes a string encoded by encode_filesystem_safe().
|
||||
|
||||
Parameter:
|
||||
|
||||
=over
|
||||
|
||||
=item $str
|
||||
|
||||
String to be decoded.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Decoded string, stripped C<utf8> flag if any.
|
||||
|
||||
=item decode_html ( $str )
|
||||
|
||||
I<Function>.
|
||||
Decodes HTML entities in a string encoded by UTF-8 or a Unicode string.
|
||||
|
||||
Parameter:
|
||||
|
||||
=over
|
||||
|
||||
=item $str
|
||||
|
||||
String to be decoded.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Decoded string, stripped C<utf8> flag if any.
|
||||
|
||||
=item encode_filesystem_safe ( $str )
|
||||
|
||||
I<Function>.
|
||||
Encodes a string $str to be suitable for filesystem.
|
||||
|
||||
Parameter:
|
||||
|
||||
=over
|
||||
|
||||
=item $str
|
||||
|
||||
String to be encoded.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Encoded string, stripped C<utf8> flag if any.
|
||||
All bytes except C<'-'>, C<'+'>, C<'.'>, C<'@'>
|
||||
and alphanumeric characters are encoded to sequences C<'_'> followed by
|
||||
two hexdigits.
|
||||
|
||||
Note that C<'/'> will also be encoded.
|
||||
|
||||
=item encode_html ( $str, [ $additional_unsafe ] )
|
||||
|
||||
I<Function>.
|
||||
Encodes characters in a string $str to HTML entities.
|
||||
By default
|
||||
C<'E<lt>'>, C<'E<gt>'>, C<'E<amp>'> and C<'E<quot>'> are encoded.
|
||||
|
||||
Parameter:
|
||||
|
||||
=over
|
||||
|
||||
=item $str
|
||||
|
||||
String to be encoded.
|
||||
|
||||
=item $additional_unsafe
|
||||
|
||||
Character or range of characters additionally encoded as entity references.
|
||||
|
||||
This optional parameter was introduced on Sympa 6.2.37b.3.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Encoded string, I<not> stripping utf8 flag if any.
|
||||
|
||||
=item encode_uri ( $str, [ omit => $chars ] )
|
||||
|
||||
I<Function>.
|
||||
Encodes potentially unsafe characters in the string using "percent" encoding
|
||||
suitable for URIs.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item $str
|
||||
|
||||
String to be encoded.
|
||||
|
||||
=item omit =E<gt> $chars
|
||||
|
||||
By default, all characters except those defined as "unreserved" in RFC 3986
|
||||
are encoded, that is, C<[^-A-Za-z0-9._~]>.
|
||||
If this parameter is given, it will prevent encoding additional characters.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Encoded string, stripped C<utf8> flag if any.
|
||||
|
||||
=item escape_chars ( $str )
|
||||
|
||||
Escape weird characters.
|
||||
|
||||
ToDo: This should be obsoleted in the future release: Would be better to use
|
||||
L</encode_filesystem_safe>.
|
||||
|
||||
=item escape_url ( $str )
|
||||
|
||||
DEPRECATED.
|
||||
Would be better to use L</"encode_uri"> or L</"mailtourl">.
|
||||
|
||||
=item foldcase ( $str )
|
||||
|
||||
I<Function>.
|
||||
Returns "fold-case" string suitable for case-insensitive match.
|
||||
For example, a code below looks for a needle in haystack not regarding case,
|
||||
even if they are non-ASCII UTF-8 strings.
|
||||
|
||||
$haystack = Sympa::Tools::Text::foldcase($HayStack);
|
||||
$needle = Sympa::Tools::Text::foldcase($NeedLe);
|
||||
if (index $haystack, $needle >= 0) {
|
||||
...
|
||||
}
|
||||
|
||||
Parameter:
|
||||
|
||||
=over
|
||||
|
||||
=item $str
|
||||
|
||||
A string.
|
||||
|
||||
=back
|
||||
|
||||
=item guessed_to_utf8( $text, [ lang, ... ] )
|
||||
|
||||
I<Function>.
|
||||
Guesses text charset considering language context
|
||||
and returns the text reencoded by UTF-8.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item $text
|
||||
|
||||
Text to be reencoded.
|
||||
|
||||
=item lang, ...
|
||||
|
||||
Language tag(s) which may be given by L<Sympa::Language/"implicated_langs">.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Reencoded text.
|
||||
If any charsets could not be guessed, C<iso-8859-1> will be used
|
||||
as the last resort, just because it covers full range of 8-bit.
|
||||
|
||||
=item mailtourl ( $email, [ decode_html =E<gt> 1 ],
|
||||
[ query =E<gt> {key =E<gt> val, ...} ] )
|
||||
|
||||
I<Function>.
|
||||
Constructs a C<mailto:> URL for given e-mail.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item $email
|
||||
|
||||
E-mail address.
|
||||
|
||||
=item decode_html =E<gt> 1
|
||||
|
||||
If set, arguments are assumed to include HTML entities.
|
||||
|
||||
=item query =E<gt> {key =E<gt> val, ...}
|
||||
|
||||
Optional query.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Constructed URL.
|
||||
|
||||
=item pad ( $str, $width )
|
||||
|
||||
Pads space a string so that result will not be narrower than given width.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item $str
|
||||
|
||||
A string.
|
||||
|
||||
=item $width
|
||||
|
||||
If $width is false value or width of $str is not less than $width,
|
||||
does nothing.
|
||||
If $width is less than C<0>, pads right.
|
||||
Otherwise, pads left.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
Padded string.
|
||||
|
||||
=item qdecode_filename ( $filename )
|
||||
|
||||
Q-Decodes web file name.
|
||||
|
||||
ToDo:
|
||||
This should be obsoleted in the future release: Would be better to use
|
||||
L</decode_filesystem_safe>.
|
||||
|
||||
=item qencode_filename ( $filename )
|
||||
|
||||
Q-Encodes web file name.
|
||||
|
||||
ToDo:
|
||||
This should be obsoleted in the future release: Would be better to use
|
||||
L</encode_filesystem_safe>.
|
||||
|
||||
=item slurp ( $file )
|
||||
|
||||
Get entire content of the file.
|
||||
Normalization by canonic_text() is applied.
|
||||
C<$file> is the path to text file.
|
||||
|
||||
=item unescape_chars ( $str )
|
||||
|
||||
Unescape weird characters.
|
||||
|
||||
ToDo: This should be obsoleted in the future release: Would be better to use
|
||||
L</decode_filesystem_safe>.
|
||||
|
||||
=item valid_email ( $string )
|
||||
|
||||
Basic check of an email address.
|
||||
|
||||
=item weburl ( $base, \@paths, [ decode_html =E<gt> 1 ],
|
||||
[ fragment =E<gt> $fragment ], [ query =E<gt> \%query ] )
|
||||
|
||||
Constructs a C<http:> or C<https:> URL under given base URI.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item $base
|
||||
|
||||
Base URI.
|
||||
|
||||
=item \@paths
|
||||
|
||||
Additional path components.
|
||||
|
||||
=item decode_html =E<gt> 1
|
||||
|
||||
If set, arguments are assumed to include HTML entities.
|
||||
Exception is $base:
|
||||
It is assumed not to include entities.
|
||||
|
||||
=item fragment =E<gt> $fragment
|
||||
|
||||
Optional fragment.
|
||||
|
||||
=item query =E<gt> \%query
|
||||
|
||||
Optional query.
|
||||
|
||||
=back
|
||||
|
||||
Returns:
|
||||
|
||||
A URI.
|
||||
|
||||
=item wrap_text ( $text, [ $init_tab, [ $subsequent_tab, [ $cols ] ] ] )
|
||||
|
||||
I<Function>.
|
||||
Returns line-wrapped text.
|
||||
|
||||
Parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item $text
|
||||
|
||||
The text to be folded.
|
||||
|
||||
=item $init_tab
|
||||
|
||||
Indentation prepended to the first line of paragraph.
|
||||
Default is C<''>, no indentation.
|
||||
|
||||
=item $subsequent_tab
|
||||
|
||||
Indentation prepended to each subsequent line of folded paragraph.
|
||||
Default is C<''>, no indentation.
|
||||
|
||||
=item $cols
|
||||
|
||||
Max number of columns of folded text.
|
||||
Default is C<78>.
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
L<Sympa::Tools::Text> appeared on Sympa 6.2a.41.
|
||||
|
||||
decode_filesystem_safe() and encode_filesystem_safe() were added
|
||||
on Sympa 6.2.10.
|
||||
|
||||
decode_html(), encode_html(), encode_uri() and mailtourl()
|
||||
were added on Sympa 6.2.14, and escape_url() was deprecated.
|
||||
|
||||
guessed_to_utf8() and pad() were added on Sympa 6.2.17.
|
||||
|
||||
canonic_text() and slurp() were added on Sympa 6.2.53b.
|
||||
|
||||
=cut
|
327
dockers/apikaz/source/Sympa/sympa_soap_client.pl
Executable file
@ -0,0 +1,327 @@
|
||||
#!/usr/bin/perl
|
||||
# -*- indent-tabs-mode: nil; -*-
|
||||
# vim:ft=perl:et:sw=4
|
||||
# $Id$
|
||||
|
||||
# Sympa - SYsteme de Multi-Postage Automatique
|
||||
#
|
||||
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
|
||||
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
|
||||
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use lib '/usr/share/sympa/lib';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use HTTP::Cookies;
|
||||
#use SOAP::Lite +trace;
|
||||
use SOAP::Lite;
|
||||
|
||||
use Sympa::Tools::Data;
|
||||
|
||||
my ($reponse, @ret, $val, %fault);
|
||||
|
||||
my $usage =
|
||||
"$0 is a perl soap client for Sympa for TEST ONLY. Use it to illustrate how to
|
||||
code access to features of Sympa soap server. Authentication can be done via
|
||||
user/password or user cookie or as a trusted remote application
|
||||
|
||||
Usage: $0 <with the following options:>
|
||||
--soap_url=<soap sympa server url>
|
||||
--service=<a sympa service>
|
||||
--trusted_application=<app name>
|
||||
--trusted_application_password=<password>
|
||||
--proxy_vars=<id=value,id2=value2>
|
||||
--service_parameters=<value1,value2,value3>
|
||||
|
||||
|
||||
OR usage: $0 <with the following options:>
|
||||
--soap_url=<soap sympa server url>
|
||||
--user_email=<email>
|
||||
--user_password=<password>
|
||||
--session_id=<sessionid>
|
||||
--service=<a sympa service>
|
||||
--service_parameters=<value1,value2,value3>
|
||||
|
||||
|
||||
OR usage: $0 <with the following options:>
|
||||
--soap_url=<soap sympa server url>
|
||||
--cookie=<sympauser cookie string>
|
||||
|
||||
Example:
|
||||
$0 --soap_url=<soap sympa server url> --cookie=sympauser=someone\@cru.fr
|
||||
";
|
||||
|
||||
my %options;
|
||||
unless (
|
||||
GetOptions(
|
||||
\%main::options, 'soap_url=s',
|
||||
'service=s', 'trusted_application=s',
|
||||
'trusted_application_password=s', 'user_email=s',
|
||||
'user_password=s', 'cookie=s',
|
||||
'proxy_vars=s', 'service_parameters=s',
|
||||
'session_id=s'
|
||||
)
|
||||
) {
|
||||
printf "";
|
||||
}
|
||||
|
||||
my $soap_url = $main::options{'soap_url'};
|
||||
unless (defined $soap_url) {
|
||||
printf "error : missing soap_url parameter\n";
|
||||
printf $usage;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $user_email = $main::options{'user_email'};
|
||||
my $user_password = $main::options{'user_password'};
|
||||
my $session_id = $main::options{'session_id'};
|
||||
my $trusted_application = $main::options{'trusted_application'};
|
||||
my $trusted_application_password =
|
||||
$main::options{'trusted_application_password'};
|
||||
my $proxy_vars = $main::options{'proxy_vars'};
|
||||
my $service = $main::options{'service'};
|
||||
my $service_parameters = $main::options{'service_parameters'};
|
||||
my $cookie = $main::options{'cookie'};
|
||||
|
||||
if (defined $trusted_application) {
|
||||
unless (defined $trusted_application_password) {
|
||||
printf "error : missing trusted_application_password parameter\n";
|
||||
printf $usage;
|
||||
exit 1;
|
||||
}
|
||||
unless (defined $service) {
|
||||
printf "error : missing service parameter\n";
|
||||
printf $usage;
|
||||
exit 1;
|
||||
}
|
||||
unless (defined $proxy_vars) {
|
||||
printf "error : missing proxy_vars parameter\n";
|
||||
printf $usage;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
play_soap_as_trusted($soap_url, $trusted_application,
|
||||
$trusted_application_password, $service, $proxy_vars,
|
||||
$service_parameters);
|
||||
} elsif ($service eq 'getUserEmailByCookie') {
|
||||
play_soap(
|
||||
soap_url => $soap_url,
|
||||
session_id => $session_id,
|
||||
service => $service
|
||||
);
|
||||
|
||||
} elsif (defined $cookie) {
|
||||
printf "error : get_email_cookie\n";
|
||||
get_email($soap_url, $cookie);
|
||||
exit 1;
|
||||
} else {
|
||||
unless (defined $session_id
|
||||
|| (defined $user_email && defined $user_password)) {
|
||||
printf
|
||||
"error : missing session_id OR user_email+user_passwors parameters\n";
|
||||
printf $usage;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
play_soap(
|
||||
soap_url => $soap_url,
|
||||
user_email => $user_email,
|
||||
user_password => $user_password,
|
||||
session_id => $session_id,
|
||||
service => $service,
|
||||
service_parameters => $service_parameters
|
||||
);
|
||||
}
|
||||
|
||||
sub play_soap_as_trusted {
|
||||
my $soap_url = shift;
|
||||
my $trusted_application = shift;
|
||||
my $trusted_application_password = shift;
|
||||
my $service = shift;
|
||||
my $proxy_vars = shift;
|
||||
my $service_parameters = shift;
|
||||
|
||||
my $soap = SOAP::Lite->new();
|
||||
$soap->uri('urn:sympasoap');
|
||||
$soap->proxy($soap_url);
|
||||
|
||||
my @parameters;
|
||||
if (defined $service_parameters) {
|
||||
@parameters = split /,/, $service_parameters;
|
||||
} else {
|
||||
@parameters = ();
|
||||
}
|
||||
my $p = join(',', @parameters);
|
||||
printf
|
||||
"calling authenticateRemoteAppAndRun( $trusted_application, $trusted_application_password, $proxy_vars,$service,$p)\n";
|
||||
|
||||
my $reponse =
|
||||
$soap->authenticateRemoteAppAndRun($trusted_application,
|
||||
$trusted_application_password, $proxy_vars, $service, \@parameters);
|
||||
print_result($reponse);
|
||||
}
|
||||
|
||||
sub get_email {
|
||||
my $soap_url = shift;
|
||||
my $cookie = shift;
|
||||
|
||||
my ($service, $reponse, @ret, $val, %fault);
|
||||
|
||||
## Cookies management
|
||||
# my $uri = URI->new($soap_url);
|
||||
|
||||
# my $cookies = HTTP::Cookies->new(ignore_discard => 1,
|
||||
# file => '/tmp/my_cookies' );
|
||||
# $cookies->load();
|
||||
printf "cookie : %s\n", $cookie;
|
||||
|
||||
my $soap = SOAP::Lite->new();
|
||||
#$soap->on_debug(sub{print@_});
|
||||
$soap->uri('urn:sympasoap');
|
||||
$soap->proxy($soap_url);
|
||||
#, cookie_jar =>$cookies);
|
||||
|
||||
print "\n\ngetEmailUserByCookie....\n";
|
||||
$reponse = $soap->getUserEmailByCookie($cookie);
|
||||
print_result($reponse);
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
sub play_soap {
|
||||
my %param = @_;
|
||||
|
||||
my $soap_url = $param{'soap_url'};
|
||||
my $user_email = $param{'user_email'};
|
||||
my $user_password = $param{'user_password'};
|
||||
my $session_id = $param{'session_id'};
|
||||
my $service = $param{'service'};
|
||||
my $service_parameters = $param{'service_parameters'};
|
||||
|
||||
my ($reponse, @ret, $val, %fault);
|
||||
|
||||
## Cookies management
|
||||
# my $uri = URI->new($soap_url);
|
||||
|
||||
my $cookies = HTTP::Cookies->new(
|
||||
ignore_discard => 1,
|
||||
file => '/tmp/my_cookies'
|
||||
);
|
||||
$cookies->load();
|
||||
printf "cookie : %s\n", $cookies->as_string();
|
||||
|
||||
my @parameters;
|
||||
@parameters = split(/,/, $service_parameters)
|
||||
if (defined $service_parameters);
|
||||
my $p = join(',', @parameters);
|
||||
foreach my $tmpParam (@parameters) {
|
||||
printf "param: %s\n", $tmpParam;
|
||||
}
|
||||
|
||||
# Change to the path of Sympa.wsdl
|
||||
#$service = SOAP::Lite->service($soap_url);
|
||||
#$reponse = $service->login($user_email,$user_password);
|
||||
#my $soap = SOAP::Lite->service($soap_url);
|
||||
|
||||
my $soap = SOAP::Lite->new() || die;
|
||||
#$soap->on_debug(sub{print@_});
|
||||
$soap->uri('urn:sympasoap');
|
||||
$soap->proxy($soap_url, cookie_jar => $cookies);
|
||||
|
||||
## Do the login unless a session_id is provided
|
||||
if ($session_id) {
|
||||
print "Using Session_id $session_id\n";
|
||||
|
||||
} else {
|
||||
print "LOGIN....\n";
|
||||
|
||||
#$reponse = $soap->casLogin($soap_url);
|
||||
$reponse = $soap->login($user_email, $user_password);
|
||||
$cookies->save;
|
||||
print_result($reponse);
|
||||
$session_id = $reponse->result;
|
||||
}
|
||||
|
||||
## Don't use authenticateAndRun for lists command
|
||||
|
||||
## Split parameters
|
||||
if ($service_parameters && $service_parameters ne '') {
|
||||
@parameters = split /,/, $service_parameters;
|
||||
}
|
||||
|
||||
if ($service eq 'lists') {
|
||||
printf "\n\nlists....\n";
|
||||
$reponse = $soap->lists();
|
||||
|
||||
} elsif ($service eq 'subscribe') {
|
||||
printf "\n\n$service....\n";
|
||||
$reponse = $soap->subscribe(@parameters);
|
||||
|
||||
} elsif ($service eq 'signoff') {
|
||||
printf "\n\n$service....\n";
|
||||
$reponse = $soap->signoff(@parameters);
|
||||
|
||||
} elsif ($service eq 'add') {
|
||||
printf "\n\n$service....\n";
|
||||
$reponse = $soap->add(@parameters);
|
||||
|
||||
} elsif ($service eq 'del') {
|
||||
printf "\n\n$service....\n";
|
||||
$reponse = $soap->del(@parameters);
|
||||
|
||||
} elsif ($service eq 'getUserEmailByCookie') {
|
||||
printf "\n\n$service....\n";
|
||||
$reponse = $soap->getUserEmailByCookie($session_id);
|
||||
|
||||
} else {
|
||||
printf "\n\nAuthenticateAndRun service=%s;(session_id=%s)....\n",
|
||||
$service, $session_id;
|
||||
$reponse =
|
||||
$soap->authenticateAndRun($user_email, $session_id, $service,
|
||||
\@parameters);
|
||||
}
|
||||
|
||||
print_result($reponse);
|
||||
|
||||
}
|
||||
|
||||
sub print_result {
|
||||
my $r = shift;
|
||||
|
||||
# If we get a fault
|
||||
if (defined $r && $r->fault) {
|
||||
print "Soap error :\n";
|
||||
my %fault = %{$r->fault};
|
||||
foreach $val (keys %fault) {
|
||||
print "$val = $fault{$val}\n";
|
||||
}
|
||||
} else {
|
||||
if (ref($r->result) =~ /^ARRAY/) {
|
||||
#printf "R: $r->result\n";
|
||||
@ret = @{$r->result};
|
||||
} elsif (ref $r->result) {
|
||||
print "Pb " . ($r->result) . "\n";
|
||||
return undef;
|
||||
} else {
|
||||
@ret = $r->result;
|
||||
}
|
||||
Sympa::Tools::Data::dump_var(\@ret, 0, \*STDOUT);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
1851
dockers/apikaz/source/app.py
Normal file
1
dockers/apikaz/source/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!-- silence is golden -->
|
9
dockers/apikaz/source/requirements.txt
Normal file
@ -0,0 +1,9 @@
|
||||
flask
|
||||
flask-restful
|
||||
flask-mail
|
||||
requests
|
||||
flasgger
|
||||
passlib
|
||||
unidecode
|
||||
email-validator
|
||||
python-ldap
|
BIN
dockers/apikaz/source/static/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
82
dockers/apikaz/source/templates/email.css
Normal file
@ -0,0 +1,82 @@
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f4f4f4;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.email-content {
|
||||
background-color: #f0f0f0; /* Light gray background */
|
||||
margin: 20px auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #dddddd;
|
||||
max-width: 600px;
|
||||
width: 90%; /* This makes the content take 90% width of its container */
|
||||
text-align: left; /* Remove text justification */
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #E16969;
|
||||
color: white;
|
||||
text-align: center;
|
||||
height: 50px; /* Fixed height for header */
|
||||
line-height: 50px; /* Vertically center the text */
|
||||
width: 100%; /* Make header full width */
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: #E16969;
|
||||
color: white;
|
||||
text-align: center;
|
||||
height: 50px; /* Fixed height for footer */
|
||||
line-height: 50px; /* Vertically center the text */
|
||||
width: 100%; /* Make footer full width */
|
||||
}
|
||||
|
||||
.header-container {
|
||||
position: relative; /* Pour positionner le logo et le texte dans le header */
|
||||
height: 50px; /* Hauteur maximale du header */
|
||||
}
|
||||
|
||||
.logo {
|
||||
position: absolute; /* Pour positionner le logo */
|
||||
max-height: 100%; /* Taille maximale du logo égale à la hauteur du header */
|
||||
top: 0; /* Aligner le logo en haut */
|
||||
left: 0; /* Aligner le logo à gauche */
|
||||
margin-right: 10px; /* Marge à droite du logo */
|
||||
}
|
||||
|
||||
.header-container h1, .footer-container p {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.footer-container p {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footer-container a {
|
||||
color: #FFFFFF; /* White color for links in footer */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer-container a:hover {
|
||||
text-decoration: underline; /* Optional: add underline on hover */
|
||||
}
|
||||
|
||||
a {
|
||||
color: #E16969; /* Same color as header/footer background for all other links */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline; /* Optional: add underline on hover */
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #E16969;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.6;
|
||||
}
|
9
dockers/apikaz/source/templates/email_footer.html
Normal file
@ -0,0 +1,9 @@
|
||||
<footer>
|
||||
<div class="footer-container">
|
||||
<p>
|
||||
© {{ now().year }} Kaz. Ici, on prend soin de vos données et on ne les vend pas !
|
||||
<br>
|
||||
<a href="https://kaz.bzh">https://kaz.bzh</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
6
dockers/apikaz/source/templates/email_header.html
Normal file
@ -0,0 +1,6 @@
|
||||
<header>
|
||||
<div class="header-container">
|
||||
<img class="logo" src="https://kaz-cloud.kaz.bzh/apps/theming/image/logo?v=33" alt="KAZ Logo">
|
||||
<h1>Kaz : Le numérique sobre, libre, éthique et local</h1>
|
||||
</div>
|
||||
</header>
|
94
dockers/apikaz/source/templates/email_inscription.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Email d'inscription'</title>
|
||||
<style>
|
||||
{% include 'email.css' %}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'email_header.html' %}
|
||||
|
||||
<div class="email-content">
|
||||
|
||||
<p>
|
||||
Bonjour {{NOM}}!<br><br>
|
||||
|
||||
Bienvenue chez KAZ!<br><br>
|
||||
|
||||
Vous disposez de :
|
||||
<ul>
|
||||
<li>une messagerie classique : <a href={{URL_WEBMAIL}}>{{URL_WEBMAIL}}</a></li>
|
||||
<li>une messagerie instantanée pour discuter au sein d'équipes : <a href={{URL_AGORA}}>{{URL_AGORA}}</a></li>
|
||||
</ul>
|
||||
Votre email et identifiant pour ces services : {{EMAIL_SOUHAITE}}<br>
|
||||
Le mot de passe : <b>{{PASSWORD}}</b><br><br>
|
||||
|
||||
Pour changer votre mot de passe de messagerie, c'est ici: <a href={{URL_MDP}}>{{URL_MDP}}</a><br>
|
||||
Si vous avez perdu votre mot de passe, c'est ici: <a href={{URL_MDP}}/?action=sendtoken>{{URL_MDP}}/?action=sendtoken</a><br><br>
|
||||
|
||||
Vous pouvez accéder à votre messagerie classique:
|
||||
<ul>
|
||||
<li>soit depuis votre webmail : <a href={{URL_WEBMAIL}}>{{URL_WEBMAIL}}</a></li>
|
||||
<li>soit depuis votre bureau virtuel : <a href={{URL_CLOUD}}>{{URL_CLOUD}}</a></li>
|
||||
<li>soit depuis un client de messagerie comme thunderbird<br>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
{% if ADMIN_ORGA == '1' %}
|
||||
<p>
|
||||
En tant qu'association/famille/société. Vous avez la possibilité d'ouvrir, quand vous le voulez, des services kaz, il vous suffit de nous le demander.<br><br>
|
||||
|
||||
Pourquoi n'ouvrons-nous pas tous les services tout de suite ? parce que nous aimons la sobriété et que nous préservons notre espace disque ;)<br>
|
||||
A quoi sert d'avoir un site web si on ne l'utilise pas, n'est-ce pas ?<br><br>
|
||||
|
||||
Par retour de mail, dites-nous de quoi vous avez besoin tout de suite entre:
|
||||
<ul>
|
||||
<li>une comptabilité : un service de gestion adhérents/clients</li>
|
||||
<li>un site web de type WordPress</li>
|
||||
<li>un cloud : bureau virtuel pour stocker des fichiers/calendriers/contacts et partager avec vos connaissances</li>
|
||||
</ul>
|
||||
Une fois que vous aurez répondu à ce mail, votre demande sera traitée manuellement.
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
Vous avez quelques docs intéressantes sur le wiki de kaz:
|
||||
<ul>
|
||||
<li>Migrer son site internet wordpress vers kaz : <a href="https://wiki.kaz.bzh/wordpress/start#migrer_son_site_wordpress_vers_kaz">https://wiki.kaz.bzh/wordpress/start#migrer_son_site_wordpress_vers_kaz</a></li>
|
||||
<li>Migrer sa messagerie vers kaz : <a href="https://wiki.kaz.bzh/messagerie/gmail/start">https://wiki.kaz.bzh/messagerie/gmail/start</a></li>
|
||||
<li>Démarrer simplement avec son cloud : <a href="https://wiki.kaz.bzh/nextcloud/start">https://wiki.kaz.bzh/messagerie/gmail/start</a></li>
|
||||
</ul>
|
||||
|
||||
Votre quota est de {{QUOTA}}GB. Si vous souhaitez plus de place pour vos fichiers ou la messagerie, faites-nous signe !<br><br>
|
||||
|
||||
Pour accéder à la messagerie instantanée et communiquer avec les membres de votre équipe ou ceux de kaz : <a href={{URL_AGORA}}/login>{{URL_AGORA}}/login</a><br>
|
||||
</p>
|
||||
|
||||
{% if ADMIN_ORGA == '1' %}
|
||||
<p>
|
||||
Comme administrateur de votre organisation, vous pouvez créer des listes de diffusion en vous rendant sur <a href={{URL_LISTE}}>{{URL_LISTE}}</a><br>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
Enfin, vous disposez de tous les autres services KAZ où l'authentification n'est pas nécessaire : <a href={{URL_SITE}}>{{URL_SITE}}</a><br><br>
|
||||
|
||||
En cas de soucis, n'hésitez pas à poser vos questions sur le canal 'Une question ? un soucis' de l'agora dispo ici : <a href={{URL_AGORA}}>{{URL_AGORA}}</a><br><br>
|
||||
|
||||
Si vous avez besoin d'accompagnement pour votre site, votre cloud, votre compta, votre migration de messagerie,...<br>nous proposons des formations mensuelles gratuites. Si vous souhaitez être accompagné par un professionnel, nous pouvons vous donner une liste de pros, référencés par KAZ.<br><br>
|
||||
|
||||
À bientôt 😉<br><br>
|
||||
|
||||
La collégiale de KAZ.<br>
|
||||
|
||||
</p>
|
||||
|
||||
</div> <!-- <div class="email-content"> -->
|
||||
|
||||
{% include 'email_footer.html' %}
|
||||
</body>
|
||||
</html>
|
1
dockers/cachet/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
47
dockers/cachet/docker-compose.yml
Normal file
@ -0,0 +1,47 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
cachet:
|
||||
# ports:
|
||||
# - 8085:8000
|
||||
image: cachethq/docker
|
||||
container_name: ${cachetServName}
|
||||
restart: ${restartPolicy}
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- cachetNet
|
||||
links:
|
||||
- db:db
|
||||
environment:
|
||||
- DB_HOST=db
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- APP_LOG=errorlog
|
||||
- APP_DEBUG=false
|
||||
- DEBUG=false
|
||||
env_file:
|
||||
- ../../secret/env-${cachetServName}
|
||||
|
||||
db:
|
||||
image: mariadb:10.5
|
||||
container_name: ${cachetDBName}
|
||||
restart: ${restartPolicy}
|
||||
networks:
|
||||
- cachetNet
|
||||
env_file:
|
||||
- ../../secret/env-${cachetDBName}
|
||||
volumes:
|
||||
#- ./initdb.d:/docker-entrypoint-initdb.d:ro
|
||||
- cachetDB:/var/lib/mysql
|
||||
- /home/sauve/:/svg/
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
|
||||
volumes:
|
||||
cachetDB:
|
||||
|
||||
networks:
|
||||
cachetNet:
|
||||
external: true
|
||||
name: cachetNet
|
1
dockers/castopod/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
55
dockers/castopod/docker-compose.yml
Normal file
@ -0,0 +1,55 @@
|
||||
services:
|
||||
app:
|
||||
image: castopod/castopod:latest
|
||||
container_name: ${castopodServName}
|
||||
volumes:
|
||||
- castopodMedia:/var/www/castopod/public/media
|
||||
environment:
|
||||
CP_BASEURL: "https://${castopodHost}.${domain}"
|
||||
CP_ANALYTICS_SALT: qldsgfliuzrbhgmkjbdbmkvb
|
||||
VIRTUAL_PORT: 8000
|
||||
CP_CACHE_HANDLER: redis
|
||||
CP_REDIS_HOST: redis
|
||||
env_file:
|
||||
- ../../secret/env-${castopodServName}
|
||||
- ../../secret/env-${castopodDBName}
|
||||
networks:
|
||||
- castopodNet
|
||||
expose:
|
||||
- 8000
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${castopodServName}.rule=Host(`${castopodHost}.${domain}`)"
|
||||
- "traefik.docker.network=castopodNet"
|
||||
|
||||
mariadb:
|
||||
image: mariadb:10.5
|
||||
container_name: ${castopodDBName}
|
||||
networks:
|
||||
- castopodNet
|
||||
volumes:
|
||||
- castopodDb:/var/lib/mysql
|
||||
env_file:
|
||||
- ../../secret/env-${castopodDBName}
|
||||
restart: unless-stopped
|
||||
|
||||
redis:
|
||||
image: redis:7.0-alpine
|
||||
container_name: castopodCache
|
||||
volumes:
|
||||
- castopodCache:/data
|
||||
networks:
|
||||
- castopodNet
|
||||
command: --requirepass ${castopodRedisPassword}
|
||||
|
||||
volumes:
|
||||
castopodMedia:
|
||||
castopodDb:
|
||||
castopodCache:
|
||||
|
||||
networks:
|
||||
castopodNet:
|
||||
external: true
|
||||
name: castopodNet
|
||||
|
13
dockers/castopod/first.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
cd $(dirname $0)
|
||||
. "${DOCKERS_ENV}"
|
||||
. "${KAZ_KEY_DIR}/SetAllPass.sh"
|
||||
|
||||
"${KAZ_BIN_DIR}/gestContainers.sh" --install -M -castopod
|
||||
|
||||
|
1
dockers/cloud/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
90
dockers/cloud/Readme.txt
Normal file
@ -0,0 +1,90 @@
|
||||
Pour l'installation de Nextcloud
|
||||
|
||||
Documentation:
|
||||
https://registry.hub.docker.com/_/nextcloud?tab=description
|
||||
https://registry.hub.docker.com/_/mariadb?tab=description
|
||||
https://blog.ssdnodes.com/blog/installing-nextcloud-docker/
|
||||
|
||||
____________________________________________________________
|
||||
Contenu du répertoire
|
||||
|
||||
____________________________________________________________
|
||||
Se placer dans le bon répertoire
|
||||
|
||||
# cd /docker/cloud
|
||||
|
||||
____________________________________________________________
|
||||
Lancement de nextcloud et nextcloudDB
|
||||
|
||||
# docker-compose up -d
|
||||
|
||||
____________________________________________________________
|
||||
Vérification
|
||||
Il y a des containers qui tournent cloudServ cloudDB (collabraServ)
|
||||
|
||||
# docker ps
|
||||
|
||||
# docker exec -ti cloudServ bash
|
||||
exit
|
||||
|
||||
# docker exec -ti cloudDB bash
|
||||
exit
|
||||
|
||||
____________________________________________________________
|
||||
Personalisation
|
||||
|
||||
Il faut attendre 2 minutes pour le lancement
|
||||
|
||||
Pour mettre en français
|
||||
emacs /var/lib/docker/volumes/cloud_cloudConfig/_data/config.php
|
||||
il faut ajouter :
|
||||
"default_language" => "fr",
|
||||
|
||||
Création des comptes.
|
||||
Application
|
||||
* Tasks
|
||||
* Calendar
|
||||
* Desk
|
||||
* Contact
|
||||
* Mail
|
||||
* Talk
|
||||
* Draw.io
|
||||
|
||||
|
||||
|
||||
* Collabora Online - Built-in CODE Server (il faut un port d'écoute)
|
||||
apt update
|
||||
apt install sudo
|
||||
sudo -u www-data php -d memory_limit=512M ./occ app:install richdocumentscode
|
||||
sudo -u www-data php -d memory_limit=512M ./occ app:update --all
|
||||
|
||||
ou
|
||||
|
||||
installer un docker collabra et
|
||||
apt update
|
||||
apt install sudo
|
||||
sudo -u www-data ./occ config:app:set --value http://89.234.186.106:9980/ richdocuments wopi_url
|
||||
sudo -u www-data ./occ richdocuments:activate-config
|
||||
|
||||
https://cloud.kaz.bzh/settings/admin/richdocuments
|
||||
|
||||
____________________________________________________________
|
||||
Mettre à jour le mot de passe dans /kaz/secret
|
||||
|
||||
____________________________________________________________
|
||||
Test
|
||||
Y a plus qu'a tester
|
||||
http://kaz.bzh:8080
|
||||
|
||||
____________________________________________________________
|
||||
Traces
|
||||
https://cloud.kaz.bzh/index.php/settings/admin/logging
|
||||
|
||||
____________________________________________________________
|
||||
Pour la sauvegarde il faut également des scripts
|
||||
|
||||
Didier le 11/12/2020
|
||||
installation du module RainLoop pour les mails
|
||||
mot passe de l' admin : voir dans /kaz/secret/SetAllPass.sh
|
||||
le module a viré pas de custom_apps dans le docker-compose
|
||||
proposition de modif du docker-compose.yml mis en commentaires.
|
77
dockers/cloud/docker-compose.yml
Normal file
@ -0,0 +1,77 @@
|
||||
version: '3.3'
|
||||
|
||||
services:
|
||||
|
||||
cloud:
|
||||
image: nextcloud
|
||||
container_name: ${nextcloudServName}
|
||||
restart: ${restartPolicy}
|
||||
depends_on:
|
||||
- db
|
||||
links:
|
||||
- db
|
||||
external_links:
|
||||
- ${smtpServName}:${smtpHost}
|
||||
# ports:
|
||||
# - 8090:80
|
||||
networks:
|
||||
- cloudNet
|
||||
- postfixNet
|
||||
- ldapNet
|
||||
volumes:
|
||||
- cloudMain:/var/www/html
|
||||
- cloudData:/var/www/html/data
|
||||
- cloudConfig:/var/www/html/config
|
||||
- cloudApps:/var/www/html/apps
|
||||
- cloudCustomApps:/var/www/html/custom_apps
|
||||
- cloudThemes:/var/www/html/themes/
|
||||
- cloudPhp:/usr/local/etc/php/conf.d/
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
env_file:
|
||||
- ../../secret/env-${nextcloudServName}
|
||||
- ../../secret/env-${nextcloudDBName}
|
||||
environment:
|
||||
- NEXTCLOUD_TRUSTED_DOMAINS=${cloudHost}.${domain}
|
||||
- SMTP_HOST=${smtpHost}
|
||||
- SMTP_PORT=25
|
||||
- MAIL_DOMAIN=${domain}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${nextcloudServName}.rule=Host(`${cloudHost}.${domain}`)"
|
||||
- "traefik.docker.network=cloudNet"
|
||||
|
||||
db:
|
||||
image: mariadb:10.5
|
||||
container_name: ${nextcloudDBName}
|
||||
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
|
||||
restart: ${restartPolicy}
|
||||
volumes:
|
||||
- cloudDB:/var/lib/mysql
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
env_file:
|
||||
- ../../secret/env-${nextcloudDBName}
|
||||
networks:
|
||||
- cloudNet
|
||||
|
||||
volumes:
|
||||
cloudDB:
|
||||
cloudMain:
|
||||
cloudData:
|
||||
cloudConfig:
|
||||
cloudApps:
|
||||
cloudCustomApps:
|
||||
cloudThemes:
|
||||
cloudPhp:
|
||||
|
||||
networks:
|
||||
cloudNet:
|
||||
external: true
|
||||
name: cloudNet
|
||||
postfixNet:
|
||||
external: true
|
||||
name: postfixNet
|
||||
ldapNet:
|
||||
external: true
|
||||
name: ldapNet
|
10
dockers/cloud/first.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
. "${DOCKERS_ENV}"
|
||||
. $KAZ_ROOT/secret/SetAllPass.sh
|
||||
|
||||
|
||||
${KAZ_BIN_DIR}/gestContainers.sh --install -M -cloud
|
BIN
dockers/cloud/media/favicon.ico
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
dockers/cloud/media/logo.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
dockers/cloud/media/logoheader.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
3
dockers/cloud/reindex.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker exec --user www-data -ti nextcloudServ bash -c "/var/www/html/occ db:add-missing-indices"
|
1
dockers/collabora/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
37
dockers/collabora/Readme.txt
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
https://help.nextcloud.com/t/socket-error-when-accessing-collabora/22486/17
|
||||
https://collabora-online-for-nextcloud.readthedocs.io/en/latest/install/
|
||||
https://www.collaboraoffice.com/code/nginx-reverse-proxy/
|
||||
|
||||
https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
|
||||
|
||||
https://cloud.kaz.bzh/settings/admin/richdocuments
|
||||
https://office.kaz.bzh/
|
||||
|
||||
docker run -t -d -p 127.0.0.1:9980:9980 -e 'domain=cloud\\.kaz\\.local --restart always --cap-add MKNOD collabora/code
|
||||
|
||||
|
||||
https://stackoverflow.com/questions/31667160/running-docker-container-iptables-no-chain-target-match-by-that-name
|
||||
|
||||
*nat
|
||||
:PREROUTING ACCEPT [144:8072]
|
||||
:INPUT ACCEPT [87:5208]
|
||||
:OUTPUT ACCEPT [118:8055]
|
||||
:POSTROUTING ACCEPT [118:8055]
|
||||
:DOCKER - [0:0]
|
||||
... your previous rules here ...
|
||||
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
|
||||
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
|
||||
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
|
||||
COMMIT
|
||||
*filter
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [5781:5099614]
|
||||
:DOCKER - [0:0]
|
||||
... your previous rules here ...
|
||||
-A FORWARD -o docker0 -j DOCKER
|
||||
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
|
||||
-A FORWARD -i docker0 -o docker0 -j ACCEPT
|
||||
COMMIT
|
40
dockers/collabora/docker-compose.yml
Normal file
@ -0,0 +1,40 @@
|
||||
version: '3.3'
|
||||
|
||||
services:
|
||||
|
||||
collabora:
|
||||
image: collabora/code
|
||||
container_name: ${officeServName}
|
||||
restart: ${restartPolicy}
|
||||
cap_add:
|
||||
- MKNOD
|
||||
- SYS_CHROOT
|
||||
- FOWNER
|
||||
# ports:
|
||||
# - 8091:9980
|
||||
env_file:
|
||||
- ../../secret/env-${officeServName}
|
||||
environment:
|
||||
- dictionaries=fr_FR en_GB es_ES
|
||||
#- domain=${cloudHost}.${domain}
|
||||
- aliasgroup1=https://.*${cloudHost}.${domain}:443
|
||||
- server_name=${site}-${officeHost}.${domain}
|
||||
- VIRTUAL_HOST=${site}-${officeHost}.${domain}
|
||||
- VIRTUAL_PORT=9980
|
||||
- VIRTUAL_PROTO=https
|
||||
- extra_params=--o:ssl.enable=false --o:ssl.termination=true
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
networks:
|
||||
collaboraNet:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${officeServName}-admin.rule=Host(`${site}-${officeHost}.${domain}`) && PathPrefix(`/(c|l)ool/adminws`)"
|
||||
- "traefik.http.routers.${officeServName}-admin.middlewares=test-adminipwhitelist@file"
|
||||
- "traefik.http.routers.${officeServName}.rule=Host(`${site}-${officeHost}.${domain}`) && ! PathPrefix(`/(c|l)ool/adminws`)"
|
||||
|
||||
networks:
|
||||
collaboraNet:
|
||||
external: true
|
||||
name: collaboraNet
|
1
dockers/dokuwiki/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
85
dockers/dokuwiki/Dockerfile
Normal file
@ -0,0 +1,85 @@
|
||||
FROM --platform=${TARGETPLATFORM:-linux/amd64} crazymax/alpine-s6:3.12
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
ARG BUILDPLATFORM
|
||||
RUN printf "I am running on ${BUILDPLATFORM:-linux/amd64}, building for ${TARGETPLATFORM:-linux/amd64}\n$(uname -a)\n"
|
||||
|
||||
LABEL maintainer="CrazyMax"
|
||||
|
||||
########################################
|
||||
# APT local cache
|
||||
# work around because COPY failed if no source file
|
||||
COPY .dummy .apt-mirror-confi[g] .proxy-confi[g] /
|
||||
RUN cp /.proxy-config /etc/profile.d/proxy.sh 2> /dev/null || true
|
||||
RUN if [ -f /.apt-mirror-config ] ; then . /.apt-mirror-config && sed -i \
|
||||
-e "s%s\?://deb.debian.org%://${APT_MIRROR_DEBIAN}%g" \
|
||||
-e "s%s\?://security.debian.org%://${APT_MIRROR_DEBIAN_SECURITY}%g" \
|
||||
-e "s%s\?://archive.ubuntu.com%://${APT_MIRROR_UBUNTU}%g" \
|
||||
-e "s%s\?://security.ubuntu.com%://${APT_MIRROR_UBUNTU_SECURITY}%g" \
|
||||
/etc/apt/sources.list; fi
|
||||
|
||||
########################################
|
||||
RUN apk --update --no-cache add \
|
||||
curl \
|
||||
imagemagick \
|
||||
inotify-tools \
|
||||
libgd \
|
||||
nginx \
|
||||
php7 \
|
||||
php7-cli \
|
||||
php7-ctype \
|
||||
php7-curl \
|
||||
php7-fpm \
|
||||
php7-gd \
|
||||
php7-imagick \
|
||||
php7-json \
|
||||
php7-ldap \
|
||||
php7-mbstring \
|
||||
php7-openssl \
|
||||
php7-pdo \
|
||||
php7-pdo_sqlite \
|
||||
php7-session \
|
||||
php7-simplexml \
|
||||
php7-sqlite3 \
|
||||
php7-xml \
|
||||
php7-zip \
|
||||
php7-zlib \
|
||||
shadow \
|
||||
su-exec \
|
||||
tar \
|
||||
tzdata \
|
||||
&& rm -rf /tmp/* /var/cache/apk/* /var/www/*
|
||||
|
||||
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS="2" \
|
||||
DOKUWIKI_VERSION="2020-07-29" \
|
||||
DOKUWIKI_MD5="8867b6a5d71ecb5203402fe5e8fa18c9" \
|
||||
TZ="UTC" \
|
||||
PUID="1500" \
|
||||
PGID="1500"
|
||||
|
||||
RUN apk --update --no-cache add -t build-dependencies \
|
||||
gnupg \
|
||||
wget \
|
||||
&& cd /tmp \
|
||||
&& wget -q "https://download.dokuwiki.org/src/dokuwiki/dokuwiki-$DOKUWIKI_VERSION.tgz" \
|
||||
&& echo "$DOKUWIKI_MD5 /tmp/dokuwiki-$DOKUWIKI_VERSION.tgz" | md5sum -c - | grep OK \
|
||||
&& tar -xzf "dokuwiki-$DOKUWIKI_VERSION.tgz" --strip 1 -C /var/www \
|
||||
&& apk del build-dependencies \
|
||||
&& rm -rf /root/.gnupg /tmp/* /var/cache/apk/*
|
||||
|
||||
COPY rootfs /
|
||||
RUN rm -f /dokuwiki.tgz
|
||||
COPY htaccess /dokuwiki/.htaccess
|
||||
|
||||
RUN chmod a+x /usr/local/bin/* \
|
||||
&& addgroup -g ${PGID} dokuwiki \
|
||||
&& adduser -D -H -u ${PUID} -G dokuwiki -s /bin/sh dokuwiki
|
||||
|
||||
EXPOSE 8000
|
||||
WORKDIR /var/www
|
||||
VOLUME [ "/data" ]
|
||||
|
||||
ENTRYPOINT [ "/init" ]
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --start-period=20s \
|
||||
CMD curl --fail http://127.0.0.1:12345/ping || exit 1
|
40
dockers/dokuwiki/docker-compose.yml
Normal file
@ -0,0 +1,40 @@
|
||||
version: '2.1'
|
||||
|
||||
services:
|
||||
|
||||
dokuwiki:
|
||||
image: mprasil/dokuwiki
|
||||
container_name: ${dokuwikiServName}
|
||||
restart: ${restartPolicy}
|
||||
# ports:
|
||||
# - 8087:80
|
||||
networks:
|
||||
- dokuwikiNet
|
||||
- postfixNet
|
||||
external_links:
|
||||
- ${smtpServName}:${smtpHost}.${domain}
|
||||
volumes:
|
||||
- "dokuwikiData:/dokuwiki/data"
|
||||
- "dokuwikiConf:/dokuwiki/conf"
|
||||
- "dokuwikiPlugins:/dokuwiki/lib/plugins"
|
||||
- "dokuwikiLibtpl:/dokuwiki/lib/tpl"
|
||||
- "dokuwikiLogs:/var/log"
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${dokuwikiServName}.rule=Host(`${dokuwikiHost}.${domain}`)"
|
||||
- "traefik.docker.network=dokuwikiNet"
|
||||
|
||||
volumes:
|
||||
dokuwikiData:
|
||||
dokuwikiConf:
|
||||
dokuwikiPlugins:
|
||||
dokuwikiLibtpl:
|
||||
dokuwikiLogs:
|
||||
|
||||
networks:
|
||||
dokuwikiNet:
|
||||
external: true
|
||||
name: dokuwikiNet
|
||||
postfixNet:
|
||||
external: true
|
||||
name: postfixNet
|
19
dockers/dokuwiki/download.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
SERV_DIR=$(cd $(dirname $0); pwd)
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
mkdir -p "${KAZ_DNLD_DIR}/dokuwiki"
|
||||
cd "${KAZ_DNLD_DIR}/dokuwiki"
|
||||
|
||||
printKazMsg "\n *** Download dokuwiki on ${KAZ_DNLD_DIR}"
|
||||
|
||||
downloadFile https://github.com/splitbrain/dokuwiki-plugin-captcha/zipball/master captcha.zip
|
||||
downloadFile https://github.com/turnermm/ckgedit/archive/current.zip ckgedit.zip
|
||||
downloadFile https://github.com/splitbrain/dokuwiki-plugin-smtp/zipball/master smtp.zip
|
||||
downloadFile https://github.com/leibler/dokuwiki-plugin-todo/archive/stable.zip todo.zip
|
||||
downloadFile https://github.com/selfthinker/dokuwiki_plugin_wrap/archive/stable.zip wrap.zip
|
||||
downloadFile http://github.com/practical-solutions/dokuwiki-plugin-wrapadd/zipball/master wrapadd.zip
|
||||
downloadFile https://github.com/Vincent31Fr/docnavwiki-template/zipball/master docnavwiki.zip
|
10
dockers/dokuwiki/first.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
cd $(dirname $0)
|
||||
. "${DOCKERS_ENV}"
|
||||
|
||||
"${KAZ_BIN_DIR}/gestContainers.sh" -M -I -wiki
|
43
dockers/dokuwiki/htaccess
Normal file
@ -0,0 +1,43 @@
|
||||
## You should disable Indexes and MultiViews either here or in the
|
||||
## global config. Symlinks maybe needed for URL rewriting.
|
||||
#Options -Indexes -MultiViews +FollowSymLinks
|
||||
|
||||
## make sure nobody gets the htaccess, README, COPYING or VERSION files
|
||||
<Files ~ "^([\._]ht|README$|VERSION$|COPYING$)">
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</IfModule>
|
||||
</Files>
|
||||
|
||||
## Don't allow access to git directories
|
||||
<IfModule alias_module>
|
||||
RedirectMatch 404 /\.git
|
||||
</IfModule>
|
||||
|
||||
## Uncomment these rules if you want to have nice URLs using
|
||||
## $conf['userewrite'] = 1 - not needed for rewrite mode 2
|
||||
RewriteEngine on
|
||||
|
||||
RewriteRule ^_media/(.*) lib/exe/fetch.php?media=$1 [QSA,L]
|
||||
RewriteRule ^_detail/(.*) lib/exe/detail.php?media=$1 [QSA,L]
|
||||
RewriteRule ^_export/([^/]+)/(.*) doku.php?do=export_$1&id=$2 [QSA,L]
|
||||
RewriteRule ^$ doku.php [L]
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule (.*) doku.php?id=$1 [QSA,L]
|
||||
RewriteRule ^index.php$ doku.php
|
||||
#
|
||||
## Not all installations will require the following line. If you do,
|
||||
## change "/dokuwiki" to the path to your dokuwiki directory relative
|
||||
## to your document root.
|
||||
#RewriteBase /dokuwiki
|
||||
#
|
||||
## If you enable DokuWikis XML-RPC interface, you should consider to
|
||||
## restrict access to it over HTTPS only! Uncomment the following two
|
||||
## rules if your server setup allows HTTPS.
|
||||
#RewriteCond %{HTTPS} !=on
|
||||
#RewriteRule ^lib/exe/xmlrpc.php$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
|
10
dockers/dokuwiki/wiki-conf/acl.auth.php
Normal file
@ -0,0 +1,10 @@
|
||||
# acl.auth.php
|
||||
# <?php exit()?>
|
||||
# Don't modify the lines above
|
||||
#
|
||||
# Access Control Lists
|
||||
#
|
||||
# Auto-generated by install script
|
||||
# Date: Sat, 13 Feb 2021 17:42:28 +0000
|
||||
* @ALL 1
|
||||
* @user 8
|
BIN
dockers/dokuwiki/wiki-conf/favicon.ico
Normal file
After Width: | Height: | Size: 8.9 KiB |
26
dockers/dokuwiki/wiki-conf/local.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/*
|
||||
* Dokuwiki's Main Configuration File - Local Settings
|
||||
* Auto-generated by config plugin
|
||||
* Run for user: felix
|
||||
* Date: Sun, 28 Feb 2021 15:56:13 +0000
|
||||
*/
|
||||
|
||||
$conf['title'] = 'Kaz';
|
||||
$conf['template'] = 'docnavwiki';
|
||||
$conf['license'] = 'cc-by-sa';
|
||||
$conf['useacl'] = 1;
|
||||
$conf['superuser'] = '@admin';
|
||||
$conf['manager'] = '@manager';
|
||||
$conf['disableactions'] = 'register';
|
||||
$conf['remoteuser'] = '';
|
||||
$conf['mailfrom'] = 'dokuwiki@kaz.bzh';
|
||||
$conf['updatecheck'] = 0;
|
||||
$conf['userewrite'] = '1';
|
||||
$conf['useslash'] = 1;
|
||||
$conf['plugin']['ckgedit']['scayt_auto'] = 'on';
|
||||
$conf['plugin']['ckgedit']['scayt_lang'] = 'French/fr_FR';
|
||||
$conf['plugin']['ckgedit']['other_lang'] = 'fr';
|
||||
$conf['plugin']['smtp']['smtp_host'] = 'smtp.kaz.bzh';
|
||||
$conf['plugin']['todo']['CheckboxText'] = 0;
|
||||
$conf['plugin']['wrap']['restrictionType'] = '1';
|
BIN
dockers/dokuwiki/wiki-conf/logo.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
13
dockers/dokuwiki/wiki-conf/users.auth.php
Normal file
@ -0,0 +1,13 @@
|
||||
# users.auth.php
|
||||
# <?php exit()?>
|
||||
# Don't modify the lines above
|
||||
#
|
||||
# Userfile
|
||||
#
|
||||
# Auto-generated by install script
|
||||
# Date: Sat, 13 Feb 2021 17:42:28 +0000
|
||||
#
|
||||
# Format:
|
||||
# login:passwordhash:Real Name:email:groups,comma,separated
|
||||
|
||||
admin:$2y$10$GYvFgViXeEUmDViplHEs7eoYV8tmbfsS8wA1vfHQ.tWgW14o9aTjy:admin:contact@kaz.bzh:admin,user
|
1
dockers/ethercalc/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
9
dockers/ethercalc/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM node:4.8
|
||||
|
||||
RUN useradd ethercalc --create-home
|
||||
RUN npm install -g ethercalc pm2 || true
|
||||
RUN rm -rf /usr/local/lib/node_modules/ethercalc/node_modules/nodemailer/ || true
|
||||
|
||||
USER ethercalc
|
||||
EXPOSE 8000
|
||||
CMD ["sh", "-c", "REDIS_HOST=$REDIS_PORT_6379_TCP_ADDR REDIS_PORT=$REDIS_PORT_6379_TCP_PORT pm2 start -x `which ethercalc` -- --cors && pm2 logs"]
|
39
dockers/ethercalc/docker-compose.yml
Normal file
@ -0,0 +1,39 @@
|
||||
version: '3.3'
|
||||
|
||||
services:
|
||||
|
||||
calc:
|
||||
image: audreyt/ethercalc
|
||||
container_name: ${ethercalcServName}
|
||||
# ports:
|
||||
# - 8082:8000
|
||||
networks:
|
||||
- ethercalcNet
|
||||
env_file:
|
||||
- ../../secret/env-${ethercalcServName}
|
||||
links:
|
||||
- redis:redis
|
||||
restart: ${restartPolicy}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${ethercalcServName}.rule=Host(`${calcHost}.${domain}`)"
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
container_name: ${ethercalcDBName}
|
||||
networks:
|
||||
- ethercalcNet
|
||||
volumes:
|
||||
- calcDB:/data
|
||||
command: redis-server --appendonly yes
|
||||
restart: ${restartPolicy}
|
||||
#on autorise 40% du cpu car sinon les docs mettent un temps fou à charger
|
||||
cpus: 0.4
|
||||
|
||||
volumes:
|
||||
calcDB:
|
||||
|
||||
networks:
|
||||
ethercalcNet:
|
||||
external: true
|
||||
name: ethercalcNet
|
1
dockers/etherpad/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
64
dockers/etherpad/docker-compose.yml
Normal file
@ -0,0 +1,64 @@
|
||||
version: '3.3'
|
||||
|
||||
services:
|
||||
|
||||
pad:
|
||||
image: etherpad/etherpad:1.8.18
|
||||
container_name: ${etherpadServName}
|
||||
restart: ${restartPolicy}
|
||||
depends_on:
|
||||
wait-for-db:
|
||||
condition: service_completed_successfully
|
||||
networks:
|
||||
- etherpadNet
|
||||
# - postfixNet
|
||||
external_links:
|
||||
- ${etherpadDBName}:padDB
|
||||
# - ${smtpServName}:${smtpHost}
|
||||
volumes:
|
||||
- etherpadPlugins:/opt/etherpad-lite/node_modules/
|
||||
- ${PWD}/settings.json:/opt/etherpad-lite/settings.json
|
||||
|
||||
env_file:
|
||||
- ../../secret/env-${etherpadServName}
|
||||
environment:
|
||||
- "DEFAULT_PAD_TEXT=––––– Ce texte est à effacer (après lecture si c’est votre première visite) ou à conserver en bas de votre pad –––––\n\nBienvenue sur notre PAD !\n\n➡ Comment commencer ?\n• Renseignez votre nom ou pseudo, en cliquant sur l’icône « utilisateur » en haut à droite.\n• Choisissez votre couleur d'écriture au même endroit.\n• Lancez-vous : écrivez sur votre pad !\n• Les contributions de chacun se synchronisent « en temps réel » sous leur propre couleur.\n\n➡ Comment partager / collaborer ?\n• Sélectionnez et copiez l'URL (l'adresse web dans la grande barre en haut à gauche du navigateur)\n• Partagez-là à vos collaborateurs et collaboratrices (email, messagerie, etc.)\n• Attention : toute personne ayant cette adresse d'accès peut modifier le pad à sa convenance.\n• Utilisez l'onglet chat (en bas à droite) pour séparer les discussions du texte sur lequel vous travaillez.\n\n➡ Comment sauvegarder ?\n• Il n'y a rien à faire : le texte est automatiquement sauvegardé, à chaque caractère tapé.\n• Marquez une version (un état du pad) en cliquant sur l’icône « étoile ».\n• Retrouvez toute l'évolution du pad et vos versions marquées d'une étoile dans l’historique (icône « horloge »).\n• Importez et exportez votre texte avec l'icône « double flèche » (formats HTML, texte brut) ou avec un copier/coller.\n\nImportant ! N’oubliez pas de conserver quelque part l’adresse web (URL) de votre pad.\n\nBon travail collaboratif :)\n\n––––– Ce texte est à effacer (après lecture si c’est votre première visite) –––––\n\n**ATTENTION**\nCETTE INSTANCE PROPOSE DES PADS À EFFACEMENT AUTOMATIQUE !\n\nVOS PADS SERONT AUTOMATIQUEMENT SUPPRIMÉS AU BOUT DE 62 JOURS (2 MOIS) SANS ÉDITION !\n\nSi le contenu de votre pad bimestriel a été effacé, c'est qu'il n'avait pas été modifié depuis plus de 62 jours consécutifs.\n"
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.pad-admin.rule=Host(`${padHost}.${domain}`) && PathPrefix(`/admin`)"
|
||||
- "traefik.http.routers.pad-admin.middlewares=test-adminipwhitelist@file"
|
||||
- "traefik.http.routers.pad.rule=Host(`${padHost}.${domain}`)"
|
||||
- "traefik.docker.network=etherpadNet"
|
||||
|
||||
padDB:
|
||||
image: mariadb:10.5
|
||||
container_name: ${etherpadDBName}
|
||||
restart: ${restartPolicy}
|
||||
networks:
|
||||
- etherpadNet
|
||||
env_file:
|
||||
- ../../secret/env-${etherpadDBName}
|
||||
volumes:
|
||||
- padDB:/var/lib/mysql
|
||||
|
||||
# wait-for-db permet d'attendre le lancement de la DB sans avoir un health_check sur le DB
|
||||
# le pb du healthcheck sur la DB : ça fait du bruit dans les logs. Si délai court beaucoup de bruit, si délai long le lancement initial est long
|
||||
wait-for-db:
|
||||
image: atkrad/wait4x:latest
|
||||
depends_on:
|
||||
- padDB
|
||||
networks:
|
||||
- etherpadNet
|
||||
command: tcp padDB:3306 -t 0 -i 1s
|
||||
|
||||
volumes:
|
||||
padDB:
|
||||
etherpadPlugins:
|
||||
|
||||
networks:
|
||||
etherpadNet:
|
||||
external: true
|
||||
name: etherpadNet
|
||||
# postfixNet:
|
||||
# external: true
|
||||
# name: postfixNet
|
650
dockers/etherpad/settings.json
Normal file
@ -0,0 +1,650 @@
|
||||
/**
|
||||
* THIS IS THE SETTINGS FILE THAT IS COPIED INSIDE THE DOCKER CONTAINER.
|
||||
*
|
||||
* By default, some runtime customizations are supported (see the
|
||||
* documentation).
|
||||
*
|
||||
* If you need more control, edit this file and rebuild the container.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file must be valid JSON. But comments are allowed
|
||||
*
|
||||
* Please edit settings.json, not settings.json.template
|
||||
*
|
||||
* Please note that starting from Etherpad 1.6.0 you can store DB credentials in
|
||||
* a separate file (credentials.json).
|
||||
*
|
||||
*
|
||||
* ENVIRONMENT VARIABLE SUBSTITUTION
|
||||
* =================================
|
||||
*
|
||||
* All the configuration values can be read from environment variables using the
|
||||
* syntax "${ENV_VAR}" or "${ENV_VAR:default_value}".
|
||||
*
|
||||
* This is useful, for example, when running in a Docker container.
|
||||
*
|
||||
* DETAILED RULES:
|
||||
* - If the environment variable is set to the string "true" or "false", the
|
||||
* value becomes Boolean true or false.
|
||||
* - If the environment variable is set to the string "null", the value
|
||||
* becomes null.
|
||||
* - If the environment variable is set to the string "undefined", the setting
|
||||
* is removed entirely, except when used as the member of an array in which
|
||||
* case it becomes null.
|
||||
* - If the environment variable is set to a string representation of a finite
|
||||
* number, the string is converted to that number.
|
||||
* - If the environment variable is set to any other string, including the
|
||||
* empty string, the value is that string.
|
||||
* - If the environment variable is unset and a default value is provided, the
|
||||
* value is as if the environment variable was set to the provided default:
|
||||
* - "${UNSET_VAR:}" becomes the empty string.
|
||||
* - "${UNSET_VAR:foo}" becomes the string "foo".
|
||||
* - "${UNSET_VAR:true}" and "${UNSET_VAR:false}" become true and false.
|
||||
* - "${UNSET_VAR:null}" becomes null.
|
||||
* - "${UNSET_VAR:undefined}" causes the setting to be removed (or be set
|
||||
* to null, if used as a member of an array).
|
||||
* - If the environment variable is unset and no default value is provided,
|
||||
* the value becomes null. THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF
|
||||
* ETHERPAD; if you want the default value to be null, you should explicitly
|
||||
* specify "null" as the default value.
|
||||
*
|
||||
* EXAMPLE:
|
||||
* "port": "${PORT:9001}"
|
||||
* "minify": "${MINIFY}"
|
||||
* "skinName": "${SKIN_NAME:colibris}"
|
||||
*
|
||||
* Would read the configuration values for those items from the environment
|
||||
* variables PORT, MINIFY and SKIN_NAME.
|
||||
*
|
||||
* If PORT and SKIN_NAME variables were not defined, the default values 9001 and
|
||||
* "colibris" would be used.
|
||||
* The configuration value "minify", on the other hand, does not have a
|
||||
* designated default value. Thus, if the environment variable MINIFY were
|
||||
* undefined, "minify" would be null.
|
||||
*
|
||||
* REMARKS:
|
||||
* 1) please note that variable substitution always needs to be quoted.
|
||||
*
|
||||
* "port": 9001, <-- Literal values. When not using
|
||||
* "minify": false substitution, only strings must be
|
||||
* "skinName": "colibris" quoted. Booleans and numbers must not.
|
||||
*
|
||||
* "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable
|
||||
* "minify": "${MINIFY:true}" substitution, put quotes around its name,
|
||||
* "skinName": "${SKIN_NAME}" even if the required value is a number or
|
||||
* a boolean.
|
||||
* Etherpad will take care of rewriting it
|
||||
* to the proper type if necessary.
|
||||
*
|
||||
* "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes
|
||||
* "minify": ${MINIFY} around variable names are missing.
|
||||
* "skinName": ${SKIN_NAME}
|
||||
*
|
||||
* 2) Beware of undefined variables and default values: nulls and empty strings
|
||||
* are different!
|
||||
*
|
||||
* This is particularly important for user's passwords (see the relevant
|
||||
* section):
|
||||
*
|
||||
* "password": "${PASSW}" // if PASSW is not defined would result in password === null
|
||||
* "password": "${PASSW:}" // if PASSW is not defined would result in password === ''
|
||||
*
|
||||
* If you want to use an empty value (null) as default value for a variable,
|
||||
* simply do not set it, without putting any colons: "${ABIWORD}".
|
||||
*
|
||||
* 3) if you want to use newlines in the default value of a string parameter,
|
||||
* use "\n" as usual.
|
||||
*
|
||||
* "defaultPadText" : "${DEFAULT_PAD_TEXT}Line 1\nLine 2"
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* Name your instance!
|
||||
*/
|
||||
"title": "${TITLE:Etherpad}",
|
||||
|
||||
/*
|
||||
* Pathname of the favicon you want to use. If null, the skin's favicon is
|
||||
* used if one is provided by the skin, otherwise the default Etherpad favicon
|
||||
* is used. If this is a relative path it is interpreted as relative to the
|
||||
* Etherpad root directory.
|
||||
*/
|
||||
"favicon": "${FAVICON:null}",
|
||||
|
||||
/*
|
||||
* Skin name.
|
||||
*
|
||||
* Its value has to be an existing directory under src/static/skins.
|
||||
* You can write your own, or use one of the included ones:
|
||||
*
|
||||
* - "no-skin": an empty skin (default). This yields the unmodified,
|
||||
* traditional Etherpad theme.
|
||||
* - "colibris": the new experimental skin (since Etherpad 1.8), candidate to
|
||||
* become the default in Etherpad 2.0
|
||||
*/
|
||||
"skinName": "${SKIN_NAME:colibris}",
|
||||
|
||||
/*
|
||||
* Skin Variants
|
||||
*
|
||||
* Use the UI skin variants builder at /p/test#skinvariantsbuilder
|
||||
*
|
||||
* For the colibris skin only, you can choose how to render the three main
|
||||
* containers:
|
||||
* - toolbar (top menu with icons)
|
||||
* - editor (containing the text of the pad)
|
||||
* - background (area outside of editor, mostly visible when using page style)
|
||||
*
|
||||
* For each of the 3 containers you can choose 4 color combinations:
|
||||
* super-light, light, dark, super-dark.
|
||||
*
|
||||
* For example, to make the toolbar dark, you will include "dark-toolbar" into
|
||||
* skinVariants.
|
||||
*
|
||||
* You can provide multiple skin variants separated by spaces. Default
|
||||
* skinVariant is "super-light-toolbar super-light-editor light-background".
|
||||
*
|
||||
* For the editor container, you can also make it full width by adding
|
||||
* "full-width-editor" variant (by default editor is rendered as a page, with
|
||||
* a max-width of 900px).
|
||||
*/
|
||||
"skinVariants": "${SKIN_VARIANTS:super-light-toolbar super-light-editor light-background}",
|
||||
|
||||
/*
|
||||
* IP and port which Etherpad should bind at.
|
||||
*
|
||||
* Binding to a Unix socket is also supported: just use an empty string for
|
||||
* the ip, and put the full path to the socket in the port parameter.
|
||||
*
|
||||
* EXAMPLE USING UNIX SOCKET:
|
||||
* "ip": "", // <-- has to be an empty string
|
||||
* "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket
|
||||
*/
|
||||
"ip": "${IP:0.0.0.0}",
|
||||
"port": "${PORT:9001}",
|
||||
|
||||
/*
|
||||
* Option to hide/show the settings.json in admin page.
|
||||
*
|
||||
* Default option is set to true
|
||||
*/
|
||||
"showSettingsInAdminPage": "${SHOW_SETTINGS_IN_ADMIN_PAGE:true}",
|
||||
|
||||
/*
|
||||
* Node native SSL support
|
||||
*
|
||||
* This is disabled by default.
|
||||
* Make sure to have the minimum and correct file access permissions set so
|
||||
* that the Etherpad server can access them
|
||||
*/
|
||||
|
||||
/*
|
||||
"ssl" : {
|
||||
"key" : "/path-to-your/epl-server.key",
|
||||
"cert" : "/path-to-your/epl-server.crt",
|
||||
"ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"]
|
||||
},
|
||||
*/
|
||||
|
||||
/*
|
||||
* The type of the database.
|
||||
*
|
||||
* You can choose between many DB drivers, for example: dirty, postgres,
|
||||
* sqlite, mysql.
|
||||
*
|
||||
* You shouldn't use "dirty" for for anything else than testing or
|
||||
* development.
|
||||
*
|
||||
*
|
||||
* Database specific settings are dependent on dbType, and go in dbSettings.
|
||||
* Remember that since Etherpad 1.6.0 you can also store this information in
|
||||
* credentials.json.
|
||||
*
|
||||
* For a complete list of the supported drivers, please refer to:
|
||||
* https://www.npmjs.com/package/ueberdb2
|
||||
*/
|
||||
|
||||
"dbType": "${DB_TYPE:dirty}",
|
||||
"dbSettings": {
|
||||
"host": "${DB_HOST:undefined}",
|
||||
"port": "${DB_PORT:undefined}",
|
||||
"database": "${DB_NAME:undefined}",
|
||||
"user": "${DB_USER:undefined}",
|
||||
"password": "${DB_PASS:undefined}",
|
||||
"charset": "${DB_CHARSET:undefined}",
|
||||
"filename": "${DB_FILENAME:var/dirty.db}"
|
||||
},
|
||||
|
||||
/*
|
||||
* The default text of a pad
|
||||
*/
|
||||
"defaultPadText" : "${DEFAULT_PAD_TEXT:Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nGet involved with Etherpad at https:\/\/etherpad.org\n}",
|
||||
|
||||
/*
|
||||
* Default Pad behavior.
|
||||
*
|
||||
* Change them if you want to override.
|
||||
*/
|
||||
"padOptions": {
|
||||
"noColors": "${PAD_OPTIONS_NO_COLORS:false}",
|
||||
"showControls": "${PAD_OPTIONS_SHOW_CONTROLS:true}",
|
||||
"showChat": "${PAD_OPTIONS_SHOW_CHAT:true}",
|
||||
"showLineNumbers": "${PAD_OPTIONS_SHOW_LINE_NUMBERS:true}",
|
||||
"useMonospaceFont": "${PAD_OPTIONS_USE_MONOSPACE_FONT:false}",
|
||||
"userName": "${PAD_OPTIONS_USER_NAME:false}",
|
||||
"userColor": "${PAD_OPTIONS_USER_COLOR:false}",
|
||||
"rtl": "${PAD_OPTIONS_RTL:false}",
|
||||
"alwaysShowChat": "${PAD_OPTIONS_ALWAYS_SHOW_CHAT:false}",
|
||||
"chatAndUsers": "${PAD_OPTIONS_CHAT_AND_USERS:false}",
|
||||
"lang": "${PAD_OPTIONS_LANG:en-gb}"
|
||||
},
|
||||
|
||||
/*
|
||||
* Pad Shortcut Keys
|
||||
*/
|
||||
"padShortcutEnabled" : {
|
||||
"altF9": "${PAD_SHORTCUTS_ENABLED_ALT_F9:true}", /* focus on the File Menu and/or editbar */
|
||||
"altC": "${PAD_SHORTCUTS_ENABLED_ALT_C:true}", /* focus on the Chat window */
|
||||
"cmdShift2": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_2:true}", /* shows a gritter popup showing a line author */
|
||||
"delete": "${PAD_SHORTCUTS_ENABLED_DELETE:true}",
|
||||
"return": "${PAD_SHORTCUTS_ENABLED_RETURN:true}",
|
||||
"esc": "${PAD_SHORTCUTS_ENABLED_ESC:true}", /* in mozilla versions 14-19 avoid reconnecting pad */
|
||||
"cmdS": "${PAD_SHORTCUTS_ENABLED_CMD_S:true}", /* save a revision */
|
||||
"tab": "${PAD_SHORTCUTS_ENABLED_TAB:true}", /* indent */
|
||||
"cmdZ": "${PAD_SHORTCUTS_ENABLED_CMD_Z:true}", /* undo/redo */
|
||||
"cmdY": "${PAD_SHORTCUTS_ENABLED_CMD_Y:true}", /* redo */
|
||||
"cmdI": "${PAD_SHORTCUTS_ENABLED_CMD_I:true}", /* italic */
|
||||
"cmdB": "${PAD_SHORTCUTS_ENABLED_CMD_B:true}", /* bold */
|
||||
"cmdU": "${PAD_SHORTCUTS_ENABLED_CMD_U:true}", /* underline */
|
||||
"cmd5": "${PAD_SHORTCUTS_ENABLED_CMD_5:true}", /* strike through */
|
||||
"cmdShiftL": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_L:true}", /* unordered list */
|
||||
"cmdShiftN": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_N:true}", /* ordered list */
|
||||
"cmdShift1": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_1:true}", /* ordered list */
|
||||
"cmdShiftC": "${PAD_SHORTCUTS_ENABLED_CMD_SHIFT_C:true}", /* clear authorship */
|
||||
"cmdH": "${PAD_SHORTCUTS_ENABLED_CMD_H:true}", /* backspace */
|
||||
"ctrlHome": "${PAD_SHORTCUTS_ENABLED_CTRL_HOME:true}", /* scroll to top of pad */
|
||||
"pageUp": "${PAD_SHORTCUTS_ENABLED_PAGE_UP:true}",
|
||||
"pageDown": "${PAD_SHORTCUTS_ENABLED_PAGE_DOWN:true}"
|
||||
},
|
||||
|
||||
/*
|
||||
* Should we suppress errors from being visible in the default Pad Text?
|
||||
*/
|
||||
"suppressErrorsInPadText": "${SUPPRESS_ERRORS_IN_PAD_TEXT:false}",
|
||||
|
||||
/*
|
||||
* If this option is enabled, a user must have a session to access pads.
|
||||
* This effectively allows only group pads to be accessed.
|
||||
*/
|
||||
"requireSession": "${REQUIRE_SESSION:false}",
|
||||
|
||||
/*
|
||||
* Users may edit pads but not create new ones.
|
||||
*
|
||||
* Pad creation is only via the API.
|
||||
* This applies both to group pads and regular pads.
|
||||
*/
|
||||
"editOnly": "${EDIT_ONLY:false}",
|
||||
|
||||
/*
|
||||
* If true, all css & js will be minified before sending to the client.
|
||||
*
|
||||
* This will improve the loading performance massively, but makes it difficult
|
||||
* to debug the javascript/css
|
||||
*/
|
||||
"minify": "${MINIFY:true}",
|
||||
|
||||
/*
|
||||
* How long may clients use served javascript code (in seconds)?
|
||||
*
|
||||
* Not setting this may cause problems during deployment.
|
||||
* Set to 0 to disable caching.
|
||||
*/
|
||||
"maxAge": "${MAX_AGE:21600}", // 60 * 60 * 6 = 6 hours
|
||||
|
||||
/*
|
||||
* Absolute path to the Abiword executable.
|
||||
*
|
||||
* Abiword is needed to get advanced import/export features of pads. Setting
|
||||
* it to null disables Abiword and will only allow plain text and HTML
|
||||
* import/exports.
|
||||
*/
|
||||
"abiword": "${ABIWORD:null}",
|
||||
|
||||
/*
|
||||
* This is the absolute path to the soffice executable.
|
||||
*
|
||||
* LibreOffice can be used in lieu of Abiword to export pads.
|
||||
* Setting it to null disables LibreOffice exporting.
|
||||
*/
|
||||
"soffice": "${SOFFICE:null}",
|
||||
|
||||
/*
|
||||
* Path to the Tidy executable.
|
||||
*
|
||||
* Tidy is used to improve the quality of exported pads.
|
||||
* Setting it to null disables Tidy.
|
||||
*/
|
||||
"tidyHtml": "${TIDY_HTML:null}",
|
||||
|
||||
/*
|
||||
* Allow import of file types other than the supported ones:
|
||||
* txt, doc, docx, rtf, odt, html & htm
|
||||
*/
|
||||
"allowUnknownFileEnds": "${ALLOW_UNKNOWN_FILE_ENDS:true}",
|
||||
|
||||
/*
|
||||
* This setting is used if you require authentication of all users.
|
||||
*
|
||||
* Note: "/admin" always requires authentication.
|
||||
*/
|
||||
"requireAuthentication": "${REQUIRE_AUTHENTICATION:false}",
|
||||
|
||||
/*
|
||||
* Require authorization by a module, or a user with is_admin set, see below.
|
||||
*/
|
||||
"requireAuthorization": "${REQUIRE_AUTHORIZATION:false}",
|
||||
|
||||
/*
|
||||
* When you use NGINX or another proxy/load-balancer set this to true.
|
||||
*
|
||||
* This is especially necessary when the reverse proxy performs SSL
|
||||
* termination, otherwise the cookies will not have the "secure" flag.
|
||||
*
|
||||
* The other effect will be that the logs will contain the real client's IP,
|
||||
* instead of the reverse proxy's IP.
|
||||
*/
|
||||
"trustProxy": "${TRUST_PROXY:false}",
|
||||
|
||||
/*
|
||||
* Settings controlling the session cookie issued by Etherpad.
|
||||
*/
|
||||
"cookie": {
|
||||
/*
|
||||
* Value of the SameSite cookie property. "Lax" is recommended unless
|
||||
* Etherpad will be embedded in an iframe from another site, in which case
|
||||
* this must be set to "None". Note: "None" will not work (the browser will
|
||||
* not send the cookie to Etherpad) unless https is used to access Etherpad
|
||||
* (either directly or via a reverse proxy with "trustProxy" set to true).
|
||||
*
|
||||
* "Strict" is not recommended because it has few security benefits but
|
||||
* significant usability drawbacks vs. "Lax". See
|
||||
* https://stackoverflow.com/q/41841880 for discussion.
|
||||
*/
|
||||
"sameSite": "${COOKIE_SAME_SITE:Lax}"
|
||||
},
|
||||
|
||||
/*
|
||||
* Privacy: disable IP logging
|
||||
*/
|
||||
"disableIPlogging": "${DISABLE_IP_LOGGING:false}",
|
||||
|
||||
/*
|
||||
* Time (in seconds) to automatically reconnect pad when a "Force reconnect"
|
||||
* message is shown to user.
|
||||
*
|
||||
* Set to 0 to disable automatic reconnection.
|
||||
*/
|
||||
"automaticReconnectionTimeout": "${AUTOMATIC_RECONNECTION_TIMEOUT:0}",
|
||||
|
||||
/*
|
||||
* By default, when caret is moved out of viewport, it scrolls the minimum
|
||||
* height needed to make this line visible.
|
||||
*/
|
||||
"scrollWhenFocusLineIsOutOfViewport": {
|
||||
|
||||
/*
|
||||
* Percentage of viewport height to be additionally scrolled.
|
||||
*
|
||||
* E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in
|
||||
* the middle of viewport, when user edits a line above of the
|
||||
* viewport
|
||||
*
|
||||
* Set to 0 to disable extra scrolling
|
||||
*/
|
||||
"percentage": {
|
||||
"editionAboveViewport": "${FOCUS_LINE_PERCENTAGE_ABOVE:0}",
|
||||
"editionBelowViewport": "${FOCUS_LINE_PERCENTAGE_BELOW:0}"
|
||||
},
|
||||
|
||||
/*
|
||||
* Time (in milliseconds) used to animate the scroll transition.
|
||||
* Set to 0 to disable animation
|
||||
*/
|
||||
"duration": "${FOCUS_LINE_DURATION:0}",
|
||||
|
||||
/*
|
||||
* Flag to control if it should scroll when user places the caret in the
|
||||
* last line of the viewport
|
||||
*/
|
||||
"scrollWhenCaretIsInTheLastLineOfViewport": "${FOCUS_LINE_CARET_SCROLL:false}",
|
||||
|
||||
/*
|
||||
* Percentage of viewport height to be additionally scrolled when user
|
||||
* presses arrow up in the line of the top of the viewport.
|
||||
*
|
||||
* Set to 0 to let the scroll to be handled as default by Etherpad
|
||||
*/
|
||||
"percentageToScrollWhenUserPressesArrowUp": "${FOCUS_LINE_PERCENTAGE_ARROW_UP:0}"
|
||||
},
|
||||
|
||||
/*
|
||||
* User accounts. These accounts are used by:
|
||||
* - default HTTP basic authentication if no plugin handles authentication
|
||||
* - some but not all authentication plugins
|
||||
* - some but not all authorization plugins
|
||||
*
|
||||
* User properties:
|
||||
* - password: The user's password. Some authentication plugins will ignore
|
||||
* this.
|
||||
* - is_admin: true gives access to /admin. Defaults to false. If you do not
|
||||
* uncomment this, /admin will not be available!
|
||||
* - readOnly: If true, this user will not be able to create new pads or
|
||||
* modify existing pads. Defaults to false.
|
||||
* - canCreate: If this is true and readOnly is false, this user can create
|
||||
* new pads. Defaults to true.
|
||||
*
|
||||
* Authentication and authorization plugins may define additional properties.
|
||||
*
|
||||
* WARNING: passwords should not be stored in plaintext in this file.
|
||||
* If you want to mitigate this, please install ep_hash_auth and
|
||||
* follow the section "secure your installation" in README.md
|
||||
*/
|
||||
|
||||
"users": {
|
||||
"admin": {
|
||||
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
|
||||
// 2) please note that if password is null, the user will not be created
|
||||
"password": "${ADMIN_PASSWORD:null}",
|
||||
"is_admin": true
|
||||
},
|
||||
"user": {
|
||||
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
|
||||
// 2) please note that if password is null, the user will not be created
|
||||
"password": "${USER_PASSWORD:null}",
|
||||
"is_admin": false
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Restrict socket.io transport methods
|
||||
*/
|
||||
"socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"],
|
||||
|
||||
"socketIo": {
|
||||
/*
|
||||
* Maximum permitted client message size (in bytes). All messages from
|
||||
* clients that are larger than this will be rejected. Large values make it
|
||||
* possible to paste large amounts of text, and plugins may require a larger
|
||||
* value to work properly, but increasing the value increases susceptibility
|
||||
* to denial of service attacks (malicious clients can exhaust memory).
|
||||
*/
|
||||
"maxHttpBufferSize": 10000
|
||||
},
|
||||
|
||||
/*
|
||||
* Allow Load Testing tools to hit the Etherpad Instance.
|
||||
*
|
||||
* WARNING: this will disable security on the instance.
|
||||
*/
|
||||
"loadTest": "${LOAD_TEST:false}",
|
||||
|
||||
/**
|
||||
* Disable dump of objects preventing a clean exit
|
||||
*/
|
||||
"dumpOnUncleanExit": false,
|
||||
|
||||
/*
|
||||
* Disable indentation on new line when previous line ends with some special
|
||||
* chars (':', '[', '(', '{')
|
||||
*/
|
||||
|
||||
/*
|
||||
"indentationOnNewLine": false,
|
||||
*/
|
||||
|
||||
/*
|
||||
* From Etherpad 1.8.3 onwards, import and export of pads is always rate
|
||||
* limited.
|
||||
*
|
||||
* The default is to allow at most 10 requests per IP in a 90 seconds window.
|
||||
* After that the import/export request is rejected.
|
||||
*
|
||||
* See https://github.com/nfriedly/express-rate-limit for more options
|
||||
*/
|
||||
"importExportRateLimiting": {
|
||||
// duration of the rate limit window (milliseconds)
|
||||
"windowMs": "${IMPORT_EXPORT_RATE_LIMIT_WINDOW:90000}",
|
||||
|
||||
// maximum number of requests per IP to allow during the rate limit window
|
||||
"max": "${IMPORT_EXPORT_MAX_REQ_PER_IP:10}"
|
||||
},
|
||||
|
||||
/*
|
||||
* From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported
|
||||
* file is always bounded.
|
||||
*
|
||||
* File size is specified in bytes. Default is 50 MB.
|
||||
*/
|
||||
"importMaxFileSize": "${IMPORT_MAX_FILE_SIZE:52428800}", // 50 * 1024 * 1024
|
||||
|
||||
/*
|
||||
* From Etherpad 1.8.5 onwards, when Etherpad is in production mode commits from individual users are rate limited
|
||||
*
|
||||
* The default is to allow at most 10 changes per IP in a 1 second window.
|
||||
* After that the change is rejected.
|
||||
*
|
||||
* See https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding for more options
|
||||
*/
|
||||
"commitRateLimiting": {
|
||||
// duration of the rate limit window (seconds)
|
||||
"duration": "${COMMIT_RATE_LIMIT_DURATION:1}",
|
||||
|
||||
// maximum number of changes per IP to allow during the rate limit window
|
||||
"points": "${COMMIT_RATE_LIMIT_POINTS:10}"
|
||||
},
|
||||
|
||||
/*
|
||||
* Toolbar buttons configuration.
|
||||
*
|
||||
* Uncomment to customize.
|
||||
*/
|
||||
|
||||
/*
|
||||
"toolbar": {
|
||||
"left": [
|
||||
["bold", "italic", "underline", "strikethrough"],
|
||||
["orderedlist", "unorderedlist", "indent", "outdent"],
|
||||
["undo", "redo"],
|
||||
["clearauthorship"]
|
||||
],
|
||||
"right": [
|
||||
["importexport", "timeslider", "savedrevision"],
|
||||
["settings", "embed"],
|
||||
["showusers"]
|
||||
],
|
||||
"timeslider": [
|
||||
["timeslider_export", "timeslider_returnToPad"]
|
||||
]
|
||||
},
|
||||
*/
|
||||
|
||||
/*
|
||||
* Expose Etherpad version in the web interface and in the Server http header.
|
||||
*
|
||||
* Do not enable on production machines.
|
||||
*/
|
||||
"exposeVersion": "${EXPOSE_VERSION:false}",
|
||||
|
||||
/*
|
||||
* The log level we are using.
|
||||
*
|
||||
* Valid values: DEBUG, INFO, WARN, ERROR
|
||||
*/
|
||||
"loglevel": "${LOGLEVEL:INFO}",
|
||||
|
||||
/*
|
||||
* Logging configuration. See log4js documentation for further information:
|
||||
* https://github.com/nomiddlename/log4js-node
|
||||
*
|
||||
* You can add as many appenders as you want here.
|
||||
*/
|
||||
"logconfig" :
|
||||
{ "appenders": [
|
||||
{ "type": "console"
|
||||
//, "category": "access"// only logs pad access
|
||||
}
|
||||
|
||||
/*
|
||||
, { "type": "file"
|
||||
, "filename": "your-log-file-here.log"
|
||||
, "maxLogSize": 1024
|
||||
, "backups": 3 // how many log files there're gonna be at max
|
||||
//, "category": "test" // only log a specific category
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
, { "type": "logLevelFilter"
|
||||
, "level": "warn" // filters out all log messages that have a lower level than "error"
|
||||
, "appender":
|
||||
{ Use whatever appender you want here }
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
, { "type": "logLevelFilter"
|
||||
, "level": "error" // filters out all log messages that have a lower level than "error"
|
||||
, "appender":
|
||||
{ "type": "smtp"
|
||||
, "subject": "An error occurred in your EPL instance!"
|
||||
, "recipients": "bar@blurdybloop.com, baz@blurdybloop.com"
|
||||
, "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message
|
||||
, "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods
|
||||
"host": "smtp.example.com", "port": 465,
|
||||
"secureConnection": true,
|
||||
"auth": {
|
||||
"user": "foo@example.com",
|
||||
"pass": "bar_foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
]
|
||||
}, // logconfig
|
||||
|
||||
/* Override any strings found in locale directories */
|
||||
"customLocaleStrings": {},
|
||||
|
||||
"ep_delete_after_delay": {
|
||||
"delay": 32000000, // 1 ans et des poussieères, in seconds
|
||||
"loop": true,
|
||||
"loopDelay": 86400, // one day, in seconds
|
||||
"deleteAtStart": true,
|
||||
"text": "Le contenu de ce pad a été effacé car il n'a pas été modifié depuis plus d'un an."
|
||||
}
|
||||
|
||||
}
|
1
dockers/framadate/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
67
dockers/framadate/Dockerfile
Normal file
@ -0,0 +1,67 @@
|
||||
FROM php:7.4-apache
|
||||
|
||||
########################################
|
||||
# APT local cache
|
||||
# work around because COPY failed if no source file
|
||||
COPY .dummy .apt-mirror-confi[g] .proxy-confi[g] /
|
||||
RUN cp /.proxy-config /etc/profile.d/proxy.sh 2> /dev/null || true
|
||||
RUN if [ -f /.apt-mirror-config ] ; then . /.apt-mirror-config && sed -i \
|
||||
-e "s%s\?://deb.debian.org%://${APT_MIRROR_DEBIAN}%g" \
|
||||
-e "s%s\?://security.debian.org%://${APT_MIRROR_DEBIAN_SECURITY}%g" \
|
||||
-e "s%s\?://archive.ubuntu.com%://${APT_MIRROR_UBUNTU}%g" \
|
||||
-e "s%s\?://security.ubuntu.com%://${APT_MIRROR_UBUNTU_SECURITY}%g" \
|
||||
/etc/apt/sources.list; fi
|
||||
|
||||
########################################
|
||||
RUN apt-get update --quiet && apt-get install -y \
|
||||
git wget zip patch \
|
||||
libicu-dev libpq-dev zlib1g-dev libicu-dev
|
||||
|
||||
RUN apt-get install -y locales locales-all
|
||||
RUN sed -i '/fr_FR.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
|
||||
ENV LC_ALL fr_FR.UTF-8
|
||||
ENV LANG fr_FR.UTF-8
|
||||
ENV LANGUAGE fr_FR:fr
|
||||
RUN update-locale LANG=fr_FR.UTF-8
|
||||
|
||||
# install framadate
|
||||
RUN mkdir /var/framadate
|
||||
WORKDIR /var/framadate
|
||||
COPY --chown=www-data git/framadate/ .
|
||||
RUN cp php.ini /usr/local/etc/php/
|
||||
|
||||
# patch bad-e-mail
|
||||
COPY dockers/framadate/patch/*.patch ./
|
||||
RUN patch adminstuds.php adminstuds.php.patch
|
||||
RUN patch create_classic_poll.php create_classic_poll.php.patch
|
||||
RUN patch create_date_poll.php create_date_poll.php.patch
|
||||
RUN patch find_polls.php find_polls.php.patch
|
||||
RUN patch locale/en.json en.json.patch
|
||||
RUN patch locale/fr.json fr.json.patch
|
||||
|
||||
# install composer setup script
|
||||
COPY dockers/framadate/composer-setup.sh /usr/local/bin/
|
||||
COPY dockers/framadate/kazdate.png /var/framadate/images/logo-framadate.png
|
||||
COPY dockers/framadate/kazclassic.png /var/framadate/images/classic.png
|
||||
COPY dockers/framadate/kazdates.png /var/framadate/images/date.png
|
||||
RUN chmod +x /usr/local/bin/composer-setup.sh
|
||||
|
||||
# install internationalization libs
|
||||
RUN docker-php-ext-configure intl
|
||||
RUN docker-php-ext-install intl
|
||||
RUN docker-php-ext-install -j$(nproc) pdo pdo_mysql
|
||||
|
||||
RUN /usr/local/bin/composer-setup.sh
|
||||
RUN php composer.phar install
|
||||
|
||||
# patch : Kaz don't use TLS
|
||||
RUN sed -e 's%$tls = true;%//XXX Kaz not use TLS // $tls = true;%' -i vendor/phpmailer/phpmailer/src/PHPMailer.php
|
||||
RUN chown -R www-data.www-data /var/framadate/
|
||||
|
||||
RUN a2enmod rewrite
|
||||
RUN cp htaccess.txt .htaccess
|
||||
|
||||
RUN mkdir /svg
|
||||
|
||||
VOLUME ["/var/framadate/app/inc", "/etc/apache2/sites-available/000-default"]
|
||||
EXPOSE 80
|
9
dockers/framadate/build.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
printKazMsg "\n *** Création du Dockerfile Framadate"
|
||||
cd "${KAZ_ROOT}"
|
||||
docker build -t datekaz . -f dockers/framadate/Dockerfile
|
18
dockers/framadate/composer-setup.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig)
|
||||
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
|
||||
|
||||
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
|
||||
then
|
||||
>&2 echo 'ERROR: Invalid installer signature'
|
||||
rm composer-setup.php
|
||||
exit 1
|
||||
fi
|
||||
|
||||
php composer-setup.php --quiet
|
||||
RESULT=$?
|
||||
rm composer-setup.php
|
||||
exit $RESULT
|
||||
|
31
dockers/framadate/config/framadate.conf
Normal file
@ -0,0 +1,31 @@
|
||||
<VirtualHost *:80>
|
||||
ServerName date.kaz.bzh
|
||||
DocumentRoot /var/framadate/
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
ServerSignature Off
|
||||
|
||||
<Location /admin/ >
|
||||
AuthType Basic
|
||||
AuthName "Administration"
|
||||
AuthUserFile "/var/framadate/admin/.htpasswd"
|
||||
Require valid-user
|
||||
</Location>
|
||||
|
||||
<Directory /var/framadate/ >
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
Options FollowSymLinks MultiViews
|
||||
<IfModule mod_dav.c>
|
||||
Dav off
|
||||
</IfModule>
|
||||
</Directory>
|
||||
|
||||
<FilesMatch "^\.ht.*">
|
||||
deny from all
|
||||
satisfy all
|
||||
ErrorDocument 403 "Access denied."
|
||||
</FilesMatch>
|
||||
|
||||
</VirtualHost>
|
||||
|
58
dockers/framadate/docker-compose.yml
Normal file
@ -0,0 +1,58 @@
|
||||
version: '3.3'
|
||||
|
||||
services:
|
||||
|
||||
framadate:
|
||||
# ports:
|
||||
# - 8088:80
|
||||
image: datekaz
|
||||
container_name: ${framadateServName}
|
||||
restart: ${restartPolicy}
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- framadateNet
|
||||
- postfixNet
|
||||
external_links:
|
||||
- ${framadateDBName}:db
|
||||
- ${smtpServName}:${smtpHost}
|
||||
volumes:
|
||||
- ./config/framadate.conf:/etc/apache2/sites-available/000-default.conf
|
||||
- dateAdmin:/var/framadate/admin
|
||||
- dateConfig:/var/framadate/app/inc
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${framadateServName}-admin.rule=Host(`${dateHost}.${domain}`) && PathPrefix(`/admin`)"
|
||||
- "traefik.http.routers.${framadateServName}-admin.middlewares=test-adminipwhitelist@file"
|
||||
- "traefik.http.routers.${framadateServName}.rule=Host(`${dateHost}.${domain}`)"
|
||||
- "traefik.docker.network=framadateNet"
|
||||
|
||||
db:
|
||||
image: mariadb:10.5
|
||||
container_name: ${framadateDBName}
|
||||
restart: ${restartPolicy}
|
||||
networks:
|
||||
- framadateNet
|
||||
env_file:
|
||||
- ../../secret/env-${framadateDBName}
|
||||
volumes:
|
||||
- dateDB:/var/lib/mysql
|
||||
- /home/sauve/:/svg/
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
|
||||
volumes:
|
||||
dateDB:
|
||||
dateConfig:
|
||||
dateAdmin:
|
||||
dateLocale:
|
||||
|
||||
networks:
|
||||
framadateNet:
|
||||
external: true
|
||||
name: framadateNet
|
||||
postfixNet:
|
||||
external: true
|
||||
name: postfixNet
|
24
dockers/framadate/download.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
SERV_DIR=$(cd $(dirname $0); pwd)
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
SRC_FRAMADATE="https://github.com/framasoft/framadate.git"
|
||||
FRAMDATE_VER="1.1.19"
|
||||
|
||||
printKazMsg "\n *** Download framadate"
|
||||
|
||||
mkdir -p "${KAZ_GIT_DIR}"
|
||||
cd "${KAZ_GIT_DIR}"
|
||||
if [ ! -d "framadate" ]; then
|
||||
git clone "${SRC_FRAMADATE}" --branch ${FRAMDATE_VER}
|
||||
fi
|
||||
|
||||
cd "${KAZ_GIT_DIR}/framadate"
|
||||
if [ -z "$(git branch | grep "${FRAMDATE_VER}")" ]; then
|
||||
printKazMsg " checkout branch ${FRAMDATE_VER}"
|
||||
git reset --hard
|
||||
git checkout ${FRAMADATE_VER}
|
||||
fi
|
44
dockers/framadate/first.sh
Executable file
@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
cd $(dirname $0)
|
||||
. "${DOCKERS_ENV}"
|
||||
. "${KAZ_KEY_DIR}/env-${framadateServName}"
|
||||
. "${KAZ_KEY_DIR}/env-${framadateDBName}"
|
||||
|
||||
FRAMADATE_URL="${httpProto}://${dateHost}.${domain}"
|
||||
|
||||
checkDockerRunning "${framadateServName}" "Framadate" || exit
|
||||
|
||||
if [ ! -f "${DOCK_LIB}/volumes/framadate_dateConfig/_data/config.php" ]; then
|
||||
printKazMsg "\n *** Premier lancement de Framadate"
|
||||
|
||||
waitUrl "${FRAMADATE_URL}"
|
||||
|
||||
${SIMU} docker exec "${framadateServName}" bash -c -i "htpasswd -bc /var/framadate/admin/.htpasswd ${HTTPD_USER} ${HTTPD_PASSWORD}"
|
||||
${SIMU} docker exec "${framadateServName}" bash -c -i "chown www-data: /var/framadate/.htaccess /var/framadate/admin/.htpasswd"
|
||||
|
||||
curl -X POST \
|
||||
-u "${HTTPD_USER}:${HTTPD_PASSWORD}" \
|
||||
-d "appMail=framadate@kaz.bzh" \
|
||||
-d "responseMail=no-reply@kaz.bzh" \
|
||||
-d "defaultLanguage=fr" \
|
||||
-d "cleanUrl=on" \
|
||||
-d "dbConnectionString=mysql:host=db;dbname=${MYSQL_DATABASE};port=3306" \
|
||||
-d "dbUser=${MYSQL_USER}" \
|
||||
-d "dbPassword=${MYSQL_PASSWORD}" \
|
||||
-d "dbPrefix=fd_" \
|
||||
-d "migrationTable=framadate_migration" \
|
||||
"${FRAMADATE_URL}/admin/install.php"
|
||||
|
||||
curl -X POST \
|
||||
-u "${HTTPD_USER}:${HTTPD_PASSWORD}" \
|
||||
"${FRAMADATE_URL}/admin/migration.php"
|
||||
|
||||
sed -e "s/'host'\s*=>\s*'[^']*',/'host' => 'smtp',/" \
|
||||
-e "s/const\s*NOMAPPLICATION\s*=\s*'[^']*';/const NOMAPPLICATION = 'Sondage';/" \
|
||||
-i "${DOCK_LIB}/volumes/framadate_dateConfig/_data/config.php"
|
||||
fi
|
BIN
dockers/framadate/kazclassic.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
dockers/framadate/kazdate.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
dockers/framadate/kazdates.png
Normal file
After Width: | Height: | Size: 32 KiB |
15
dockers/framadate/patch/adminstuds.php.patch
Normal file
@ -0,0 +1,15 @@
|
||||
--- adminstuds.php 2022-02-05 09:09:45.256310389 +0100
|
||||
+++ adminstuds.php-new 2022-02-05 08:49:40.952269857 +0100
|
||||
@@ -84,6 +84,12 @@
|
||||
$message = new Message('success', __('adminstuds', 'The poll is created.'));
|
||||
}
|
||||
|
||||
+$messageBadEmail = $sessionService->get("Framadate", "messageBadEmail", FALSE);
|
||||
+if ($messageBadEmail) {
|
||||
+ $sessionService->remove("Framadate", "messageBadEmail");
|
||||
+ $message = new Message('danger', __('adminstuds', "Bad e-mail. Can't send links"));
|
||||
+}
|
||||
+
|
||||
// -------------------------------
|
||||
// Update poll info
|
||||
// -------------------------------
|
17
dockers/framadate/patch/create_classic_poll.php.patch
Normal file
@ -0,0 +1,17 @@
|
||||
--- create_classic_poll.php 2022-02-05 09:09:45.256310389 +0100
|
||||
+++ create_classic_poll.php-new 2022-02-05 09:03:08.924297050 +0100
|
||||
@@ -83,8 +83,12 @@
|
||||
$message_admin .= sprintf(' :<br/><br/><a href="%1$s">%1$s</a>', Utils::getUrlSondage($admin_poll_id, true));
|
||||
|
||||
if ($mailService->isValidEmail($form->admin_mail)) {
|
||||
- $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Author\'s message') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message_admin);
|
||||
- $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'For sending to the polled users') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message);
|
||||
+ try {
|
||||
+ $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Author\'s message') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message_admin);
|
||||
+ $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'For sending to the polled users') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message);
|
||||
+ } catch (Exception $e) {
|
||||
+ $sessionService->set("Framadate", "messageBadEmail", TRUE);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
17
dockers/framadate/patch/create_date_poll.php.patch
Normal file
@ -0,0 +1,17 @@
|
||||
--- create_date_poll.php 2022-02-05 09:09:45.256310389 +0100
|
||||
+++ create_date_poll.php-new 2022-02-05 08:47:40.708265810 +0100
|
||||
@@ -210,8 +210,12 @@
|
||||
$message_admin = sprintf($message_admin, Utils::getUrlSondage($admin_poll_id, true));
|
||||
|
||||
if ($mailService->isValidEmail($form->admin_mail)) {
|
||||
- $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Author\'s message') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message_admin);
|
||||
- $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'For sending to the polled users') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message);
|
||||
+ try {
|
||||
+ $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Author\'s message') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message_admin);
|
||||
+ $mailService->send($form->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'For sending to the polled users') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($form->title), $message);
|
||||
+ } catch (Exception $e) {
|
||||
+ $sessionService->set("Framadate", "messageBadEmail", TRUE);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
10
dockers/framadate/patch/en.json.patch
Normal file
@ -0,0 +1,10 @@
|
||||
--- locale/en.json 2022-02-05 09:09:45.256310389 +0100
|
||||
+++ locale/en.json-new 2022-02-05 08:52:37.688275805 +0100
|
||||
@@ -439,6 +439,7 @@
|
||||
"Remove the comments": "Remove the comments",
|
||||
"Remove the votes": "Remove the votes",
|
||||
"The poll is created.": "The poll was created.",
|
||||
+ "Bad e-mail. Can't send links": "Bad e-mail. Can't send links",
|
||||
"Vote added": "Vote added",
|
||||
"Vote deleted": "Vote deleted",
|
||||
"Vote updated": "Vote updated",
|
17
dockers/framadate/patch/find_polls.php.patch
Normal file
@ -0,0 +1,17 @@
|
||||
--- find_polls.php 2022-02-05 09:09:45.256310389 +0100
|
||||
+++ find_polls.php-new 2022-02-05 09:07:28.072305772 +0100
|
||||
@@ -43,8 +43,12 @@
|
||||
$smarty->assign('polls', $polls);
|
||||
$body = $smarty->fetch('mail/find_polls.tpl');
|
||||
|
||||
- $mailService->send($mail, __('FindPolls', 'List of your polls') . ' - ' . NOMAPPLICATION, $body, 'SEND_POLLS');
|
||||
- $message = new Message('success', __('FindPolls', 'Polls sent'));
|
||||
+ try {
|
||||
+ $mailService->send($mail, __('FindPolls', 'List of your polls') . ' - ' . NOMAPPLICATION, $body, 'SEND_POLLS');
|
||||
+ $message = new Message('success', __('FindPolls', 'Polls sent'));
|
||||
+ } catch (Exception $e) {
|
||||
+ $message = new Message('warning', __('Error', 'No polls found'));
|
||||
+ }
|
||||
} else {
|
||||
$message = new Message('warning', __('Error', 'No polls found'));
|
||||
}
|
10
dockers/framadate/patch/fr.json.patch
Normal file
@ -0,0 +1,10 @@
|
||||
--- locale/fr.json 2022-02-05 09:09:45.256310389 +0100
|
||||
+++ locale/fr.json-new 2022-02-05 08:57:14.468285120 +0100
|
||||
@@ -435,6 +435,7 @@
|
||||
"Remove the comments": "Supprimer les commentaires",
|
||||
"Remove the votes": "Supprimer les votes",
|
||||
"The poll is created.": "Le sondage a été créé.",
|
||||
+ "Bad e-mail. Can't send links": "Mauvais mèl. Les liens n'ont pu être envoyés.",
|
||||
"Vote added": "Vote ajouté",
|
||||
"Vote deleted": "Vote supprimé",
|
||||
"Vote updated": "Vote mis à jour",
|
1
dockers/gitea/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
53
dockers/gitea/docker-compose.yml
Normal file
@ -0,0 +1,53 @@
|
||||
version: '3'
|
||||
services:
|
||||
web:
|
||||
image: gitea/gitea
|
||||
container_name: ${gitServName}
|
||||
restart: ${restartPolicy}
|
||||
ports:
|
||||
# - 8088:3000/tcp
|
||||
- 2202:22/tcp
|
||||
networks:
|
||||
- giteaNet
|
||||
- postfixNet
|
||||
external_links:
|
||||
- ${smtpServName}:${smtpHost}
|
||||
volumes:
|
||||
- gitData:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${gitServName}.rule=Host(`${gitHost}.${domain}`)"
|
||||
- "traefik.http.services.${gitServName}.loadbalancer.server.port=3000"
|
||||
- "traefik.docker.network=giteaNet"
|
||||
|
||||
db:
|
||||
image: mariadb:10.5
|
||||
container_name: ${gitDBName}
|
||||
restart: ${restartPolicy}
|
||||
env_file:
|
||||
- ../../secret/env-${gitDBName}
|
||||
volumes:
|
||||
- gitDB:/var/lib/mysql
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
networks:
|
||||
- giteaNet
|
||||
|
||||
volumes:
|
||||
gitDB:
|
||||
gitData:
|
||||
|
||||
networks:
|
||||
giteaNet:
|
||||
external: true
|
||||
name: giteaNet
|
||||
postfixNet:
|
||||
external: true
|
||||
name: postfixNet
|
72
dockers/gitea/first.sh
Executable file
@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
cd $(dirname $0)
|
||||
. "${DOCKERS_ENV}"
|
||||
. "${KAZ_KEY_DIR}/env-${gitServName}"
|
||||
. "${KAZ_KEY_DIR}/env-${gitDBName}"
|
||||
|
||||
GIT_URL="${httpProto}://${gitHost}.${domain}"
|
||||
|
||||
checkDockerRunning "${gitServName}" "Gitea" || exit
|
||||
|
||||
if ! grep -q "INSTALL_LOCK\s*=\s*true" "${DOCK_LIB}/volumes/gitea_gitData/_data/gitea/conf/app.ini" 2>/dev/null ; then
|
||||
printKazMsg "\n *** Premier lancement de GIT"
|
||||
|
||||
waitUrl "${GIT_URL}"
|
||||
|
||||
curl -X POST \
|
||||
--data-urlencode "admin_confirm_passwd=${pass_admin}" \
|
||||
--data-urlencode "admin_email=${admin_email}" \
|
||||
--data-urlencode "admin_name=${user_admin}" \
|
||||
--data-urlencode "admin_passwd=${pass_admin}" \
|
||||
--data-urlencode "allow_only_external_registration=" \
|
||||
--data-urlencode "app_name=Gitea: Git with a cup of tea" \
|
||||
--data-urlencode "app_url=${httpProto}://${gitHost}.${domain}/" \
|
||||
--data-urlencode "charset=utf8" \
|
||||
--data-urlencode "db_host=db:3306" \
|
||||
--data-urlencode "db_name=${MYSQL_DATABASE}" \
|
||||
--data-urlencode "db_passwd=${MYSQL_PASSWORD}" \
|
||||
--data-urlencode "db_schema=" \
|
||||
--data-urlencode "db_path=/data/gitea/gitea.db" \
|
||||
--data-urlencode "db_type=mysql" \
|
||||
--data-urlencode "db_user=${MYSQL_USER}" \
|
||||
--data-urlencode "default_allow_create_organization=on" \
|
||||
--data-urlencode "default_enable_timetracking=on" \
|
||||
--data-urlencode "default_keep_email_private=" \
|
||||
--data-urlencode "disable_gravatar=" \
|
||||
--data-urlencode "disable_registration=on" \
|
||||
--data-urlencode "domain=${gitHost}.${domain}" \
|
||||
--data-urlencode "enable_captcha=" \
|
||||
--data-urlencode "enable_federated_avatar=on" \
|
||||
--data-urlencode "enable_open_id_sign_in=" \
|
||||
--data-urlencode "enable_open_id_sign_up=" \
|
||||
--data-urlencode "http_port=3000" \
|
||||
--data-urlencode "lfs_root_path=/data/git/lfs" \
|
||||
--data-urlencode "log_root_path=/data/gitea/log" \
|
||||
--data-urlencode "mail_notify=on" \
|
||||
--data-urlencode "no_reply_address=noreply.localhost" \
|
||||
--data-urlencode "offline_mode=" \
|
||||
--data-urlencode "password_algorithm=pbkdf2" \
|
||||
--data-urlencode "register_confirm=on" \
|
||||
--data-urlencode "repo_root_path=/data/git/repositories" \
|
||||
--data-urlencode "require_sign_in_view=" \
|
||||
--data-urlencode "run_user=git" \
|
||||
--data-urlencode "smtp_from=admin@${smtpHost}.${domain}" \
|
||||
--data-urlencode "smtp_host=${smtpHost}.${domain}" \
|
||||
--data-urlencode "smtp_passwd=" \
|
||||
--data-urlencode "smtp_user=" \
|
||||
--data-urlencode "ssh_port=2202" \
|
||||
--data-urlencode "ssl_mode=disable" \
|
||||
"${httpProto}://${gitHost}.${domain}/"
|
||||
|
||||
fi
|
||||
|
||||
# https://docs.gitea.io/en-us/customizing-gitea/
|
||||
DATA_DIR="${DOCK_VOL}/gitea_gitData/_data/gitea"
|
||||
mkdir -p "${DATA_DIR}/public/img"
|
||||
cp "$(dirname $0)/logo.svg" "${DATA_DIR}/public/img/logo.svg"
|
||||
chown -R 1000:1000 "${DATA_DIR}/public/"
|
979
dockers/gitea/logo.svg
Normal file
@ -0,0 +1,979 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 640 640"
|
||||
style="enable-background:new 0 0 640 640"
|
||||
xml:space="preserve"
|
||||
width="32"
|
||||
height="32"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"><metadata
|
||||
id="metadata14"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs12" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2159"
|
||||
inkscape:window-height="1675"
|
||||
id="namedview10"
|
||||
showgrid="false"
|
||||
inkscape:zoom="38.229526"
|
||||
inkscape:cx="16.59547"
|
||||
inkscape:cy="20.409433"
|
||||
inkscape:window-x="960"
|
||||
inkscape:window-y="288"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg8" /><path
|
||||
style="fill:#fff"
|
||||
d="m395.9 484.2-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5 21.2-17.9 33.8-11.8 17.2 8.3 27.1 13 27.1 13l-.1-109.2 16.7-.1.1 117.1s57.4 24.2 83.1 40.1c3.7 2.3 10.2 6.8 12.9 14.4 2.1 6.1 2 13.1-1 19.3l-61 126.9c-6.2 12.7-21.4 18.1-33.9 12z"
|
||||
id="path2" /><path
|
||||
style="fill:#609926"
|
||||
d="M622.7 149.8c-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.3.3-26.5.6-39.6.7v117.2c-5.5-2.6-11.1-5.3-16.6-7.9 0-36.4-.1-109.2-.1-109.2-29 .4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5c-9.8-.6-22.5-2.1-39 1.5-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5 45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62 63 0 188.9-.1 188.9-.1s12 .1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4S547 483 565 451.5c5.5-9.7 10.1-19.1 14.1-28 0 0 55.2-117.1 55.2-231.1-1.1-34.5-9.6-40.6-11.6-42.6zM125.6 353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1s7.1 59.4 15.7 94.2c7.2 29.2 24.8 77.7 24.8 77.7s-26.1-3.1-43-9.1zm300.3 107.6s-6.1 14.5-19.6 15.4c-5.8.4-10.3-1.2-10.3-1.2s-.3-.1-5.3-2.1l-112.9-55s-10.9-5.7-12.8-15.6c-2.2-8.1 2.7-18.1 2.7-18.1L322 273s4.8-9.7 12.2-13c.6-.3 2.3-1 4.5-1.5 8.1-2.1 18 2.8 18 2.8L467.4 315s12.6 5.7 15.3 16.2c1.9 7.4-.5 14-1.8 17.2-6.3 15.4-55 113.1-55 113.1z"
|
||||
id="path4" /><image
|
||||
width="169.37718"
|
||||
height="142.20097"
|
||||
preserveAspectRatio="none"
|
||||
xlink:href="data:image/png;base64,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
|
||||
KejLS1ynOYwUFrAICSIU1FBBFTbitOqkWMjQftLHP+T6JXIp5KqAkWMeG9Agu37wP/jdrVVMTHhJ
|
||||
kSQQenGcjxEgvAs0647zfew4zRMg+Axc6W3/RgOY/iS93tZiR0D/NnBx3daUPeByBxh8MmRTdqUg
|
||||
TaFYBN7P6JvywMAt0Lvq9dbax+kDkKWu0jfAwSEwWqLsNZ9393T29u+ZVn8/LMtyi3eG6wwAABEr
|
||||
aVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBN
|
||||
cENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEv
|
||||
IiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0
|
||||
dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3Jp
|
||||
cHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczppcHRjRXh0PSJodHRwOi8vaXB0Yy5vcmcvc3Rk
|
||||
L0lwdGM0eG1wRXh0LzIwMDgtMDItMjkvIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9i
|
||||
ZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94
|
||||
YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6cGx1cz0iaHR0cDovL25zLnVz
|
||||
ZXBsdXMub3JnL2xkZi94bXAvMS4wLyIKICAgIHhtbG5zOkdJTVA9Imh0dHA6Ly93d3cuZ2ltcC5v
|
||||
cmcveG1wLyIKICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIK
|
||||
ICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgeG1sbnM6
|
||||
eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpEb2N1bWVudElEPSJn
|
||||
aW1wOmRvY2lkOmdpbXA6ZGVhOTA4ZDItYTJkZC00NDhlLWIxNzItM2FjNjRlM2E5ODI5IgogICB4
|
||||
bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNkZGQ0M2U0LTk5ZmUtNDYzOC04OGNkLWYwODg0ZDU2
|
||||
NzgyZiIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjkzYjIyYTZiLWI4Mzkt
|
||||
NDZjMC05MDc1LTU0NzdjYTk1NGMxYyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9y
|
||||
bT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNjU0NDMwNTg2MjYzMzk1IgogICBHSU1QOlZl
|
||||
cnNpb249IjIuMTAuMjIiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICB0aWZmOk9yaWVudGF0
|
||||
aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAgMi4xMCI+CiAgIDxpcHRjRXh0OkxvY2F0
|
||||
aW9uQ3JlYXRlZD4KICAgIDxyZGY6QmFnLz4KICAgPC9pcHRjRXh0OkxvY2F0aW9uQ3JlYXRlZD4K
|
||||
ICAgPGlwdGNFeHQ6TG9jYXRpb25TaG93bj4KICAgIDxyZGY6QmFnLz4KICAgPC9pcHRjRXh0Okxv
|
||||
Y2F0aW9uU2hvd24+CiAgIDxpcHRjRXh0OkFydHdvcmtPck9iamVjdD4KICAgIDxyZGY6QmFnLz4K
|
||||
ICAgPC9pcHRjRXh0OkFydHdvcmtPck9iamVjdD4KICAgPGlwdGNFeHQ6UmVnaXN0cnlJZD4KICAg
|
||||
IDxyZGY6QmFnLz4KICAgPC9pcHRjRXh0OlJlZ2lzdHJ5SWQ+CiAgIDx4bXBNTTpIaXN0b3J5Pgog
|
||||
ICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAg
|
||||
ICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmMwY2Y5
|
||||
ZmZkLTYwMmItNDI4YS04YjQ1LTIwYmM2MGY2MjhmNiIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2Vu
|
||||
dD0iR2ltcCAyLjEwIChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IiswMTowMCIvPgogICAgIDxy
|
||||
ZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIK
|
||||
ICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowYjE2ZGEzMy05MjU3LTRmYzEtYTBmZS00
|
||||
MzQxMTBhMjEwMWUiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgp
|
||||
IgogICAgICBzdEV2dDp3aGVuPSIrMDE6MDAiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFj
|
||||
dGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNl
|
||||
SUQ9InhtcC5paWQ6NWU3MGZiMTUtMmVlZi00Y2Q3LThmZWQtNzlmMGZiZDdiMjZhIgogICAgICBz
|
||||
dEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0i
|
||||
KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICAgPHBsdXM6SW1h
|
||||
Z2VTdXBwbGllcj4KICAgIDxyZGY6U2VxLz4KICAgPC9wbHVzOkltYWdlU3VwcGxpZXI+CiAgIDxw
|
||||
bHVzOkltYWdlQ3JlYXRvcj4KICAgIDxyZGY6U2VxLz4KICAgPC9wbHVzOkltYWdlQ3JlYXRvcj4K
|
||||
ICAgPHBsdXM6Q29weXJpZ2h0T3duZXI+CiAgICA8cmRmOlNlcS8+CiAgIDwvcGx1czpDb3B5cmln
|
||||
aHRPd25lcj4KICAgPHBsdXM6TGljZW5zb3I+CiAgICA8cmRmOlNlcS8+CiAgIDwvcGx1czpMaWNl
|
||||
bnNvcj4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||
ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0
|
||||
IGVuZD0idyI/Pkb7dcoAAAAGYktHRADbANkA3uRVBFsAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAH
|
||||
dElNRQfmBgUMAwZ/A1g/AAAgAElEQVR42uy9eZgcV3X3/62enqVnVBpJlhpJbll2C8Z4DGM8ICNb
|
||||
ODEOYbUDNptj1hicGAKBF17DQwgYeAOYNYQt8IMshDWscQwBh8TYxvsi24ot22N5ZEkjjdUaLaOe
|
||||
fbrr/v64dapuVVdvMzU9I/X38zz1dHV1d3V19b3nfu+5555rgcRJAoDjPloAiu7xNgAzAE4GcDmA
|
||||
twI4zX3vTgA3AfhPALcAmHI/3wJg1jhn+DvgvkeFXieEkGa2vyamjWx17fIFAF7gbqcCSAHIuXb4
|
||||
nwE86H6uUOG8hCwJUu7jcwFscwv7rPtYdB9luwXAG933W0aFSITO1Wock/cQQkgz02HYxYRxPOm+
|
||||
9m5XRBSNTYW2HIC3uTaVdpUsGdpCYkAafwB4JoDdhpKWwj3tHpty1bIU+FsBnO2eL1nm+1qMCtDK
|
||||
208IIR42gHZ3/9lu5+2YISSmXZsrNnkWwKTx+qWuje3irSRLiaShfltc4XG9W2gnoIdKVJnNLOCH
|
||||
AbzTPV/SEBoJw8ORilDrhBDSbLQbdtH0PFwK4JBhV8dcG2x6LwrG/pRhf1cb56JHgywZLFdYADrm
|
||||
wiy4UqAdd3/G8GQUDHUt7/24ca72UIEHCz0hhARsYZtrK9+F0uFoU1gUDZtbMI6Nujb4IxGdRkIW
|
||||
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
|
||||
|
||||
"
|
||||
id="image849"
|
||||
x="413.95416"
|
||||
y="96.540276"
|
||||
transform="rotate(26.21162)"
|
||||
inkscape:transform-center-x="38.617587"
|
||||
inkscape:transform-center-y="-16.964991" /></svg>
|
After Width: | Height: | Size: 72 KiB |
1
dockers/grafana/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
67
dockers/grafana/docker-compose.yml
Normal file
@ -0,0 +1,67 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
|
||||
prometheus:
|
||||
image: prom/prometheus:v2.15.2
|
||||
restart: unless-stopped
|
||||
container_name: ${prometheusServName}
|
||||
volumes:
|
||||
- ./prometheus/:/etc/prometheus/
|
||||
- prometheus:/prometheus
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
command:
|
||||
- "--web.route-prefix=/"
|
||||
- "--web.external-url=https://${site}.${domain}/prometheus"
|
||||
- "--config.file=/etc/prometheus/prometheus.yml"
|
||||
- "--storage.tsdb.path=/prometheus"
|
||||
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
|
||||
- "--web.console.templates=/usr/share/prometheus/consoles"
|
||||
networks:
|
||||
- traefikNet
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.prometheus-secure.entrypoints=websecure"
|
||||
- "traefik.http.middlewares.prometheus-stripprefix.stripprefix.prefixes=/prometheus"
|
||||
- "traefik.http.routers.prometheus-secure.rule=Host(`${site}.${domain}`) && PathPrefix(`/prometheus`)"
|
||||
# - "traefik.http.routers.prometheus-secure.tls=true"
|
||||
- "traefik.http.routers.prometheus-secure.middlewares=prometheus-stripprefix,test-adminipwhitelist@file,traefik-auth"
|
||||
- "traefik.http.routers.prometheus-secure.service=prometheus"
|
||||
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
|
||||
- "traefik.docker.network=traefikNet"
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:6.6.1
|
||||
restart: unless-stopped
|
||||
container_name: ${grafanaServName}
|
||||
volumes:
|
||||
- grafana:/var/lib/grafana
|
||||
- ./grafana/provisioning:/etc/grafana/provisioning
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
env_file:
|
||||
- grafana.env
|
||||
depends_on:
|
||||
- prometheus
|
||||
networks:
|
||||
- traefikNet
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.grafana-secure.entrypoints=websecure"
|
||||
- "traefik.http.middlewares.grafana-stripprefix.stripprefix.prefixes=/grafana"
|
||||
- "traefik.http.routers.grafana-secure.rule=Host(`${site}.${domain}`) && PathPrefix(`/grafana`)"
|
||||
# - "traefik.http.routers.grafana-secure.tls=true"
|
||||
- "traefik.http.routers.grafana-secure.service=grafana"
|
||||
- "traefik.http.routers.grafana-secure.middlewares=grafana-stripprefix,test-adminipwhitelist@file,traefik-auth"
|
||||
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
|
||||
- "traefik.docker.network=traefikNet"
|
||||
|
||||
networks:
|
||||
traefikNet:
|
||||
external: true
|
||||
name: traefikNet
|
||||
|
||||
volumes:
|
||||
prometheus:
|
||||
grafana:
|
6
dockers/grafana/grafana.env
Normal file
@ -0,0 +1,6 @@
|
||||
GF_AUTH_ANONYMOUS_ENABLED=true
|
||||
GF_AUTH_BASIC_ENABLED=false
|
||||
GF_AUTH_PROXY_ENABLED=false
|
||||
GF_USERS_ALLOW_SIGN_UP=false
|
||||
GF_INSTALL_PLUGINS=grafana-piechart-panel
|
||||
GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana
|
@ -0,0 +1,21 @@
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
# <string> provider name
|
||||
- name: 'default'
|
||||
# <int> org id. will default to orgId 1 if not specified
|
||||
orgId: 1
|
||||
# <string, required> name of the dashboard folder. Required
|
||||
folder: ''
|
||||
# <string> folder UID. will be automatically generated if not specified
|
||||
folderUid: ''
|
||||
# <string, required> provider type. Required
|
||||
type: file
|
||||
# <bool> disable dashboard deletion
|
||||
disableDeletion: false
|
||||
# <bool> enable dashboard editing
|
||||
editable: true
|
||||
# <int> how often Grafana will scan for changed dashboards
|
||||
updateIntervalSeconds: 10
|
||||
options:
|
||||
path: /etc/grafana/provisioning/dashboards
|
@ -0,0 +1,50 @@
|
||||
# config file version
|
||||
apiVersion: 1
|
||||
|
||||
# list of datasources that should be deleted from the database
|
||||
deleteDatasources:
|
||||
- name: Prometheus
|
||||
orgId: 1
|
||||
|
||||
# list of datasources to insert/update depending
|
||||
# whats available in the database
|
||||
datasources:
|
||||
# <string, required> name of the datasource. Required
|
||||
- name: Prometheus
|
||||
# <string, required> datasource type. Required
|
||||
type: prometheus
|
||||
# <string, required> access mode. direct or proxy. Required
|
||||
access: proxy
|
||||
# <int> org id. will default to orgId 1 if not specified
|
||||
orgId: 1
|
||||
# <string> url
|
||||
url: http://prometheus:9090
|
||||
# <string> database password, if used
|
||||
password:
|
||||
# <string> database user, if used
|
||||
user:
|
||||
# <string> database name, if used
|
||||
database:
|
||||
# <bool> enable/disable basic auth
|
||||
basicAuth: false
|
||||
# <string> basic auth username
|
||||
basicAuthUser:
|
||||
# <string> basic auth password
|
||||
basicAuthPassword:
|
||||
# <bool> enable/disable with credentials headers
|
||||
withCredentials:
|
||||
# <bool> mark as default datasource. Max one per org
|
||||
isDefault: true
|
||||
# <map> fields that will be converted to json and stored in json_data
|
||||
jsonData:
|
||||
graphiteVersion: "1.1"
|
||||
tlsAuth: false
|
||||
tlsAuthWithCACert: false
|
||||
# <string> json object of data that will be encrypted.
|
||||
secureJsonData:
|
||||
tlsCACert: "..."
|
||||
tlsClientCert: "..."
|
||||
tlsClientKey: "..."
|
||||
version: 1
|
||||
# <bool> allow users to edit datasources from the UI.
|
||||
editable: true
|
11
dockers/grafana/prometheus/alert.rules
Normal file
@ -0,0 +1,11 @@
|
||||
groups:
|
||||
- name: traefik
|
||||
rules:
|
||||
- alert: service_down
|
||||
expr: up == 0
|
||||
for: 2m
|
||||
labels:
|
||||
severity: page
|
||||
annotations:
|
||||
summary: "Instance {{ $labels.instance }} down"
|
||||
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 2 minutes"
|
12
dockers/grafana/prometheus/prometheus.yml
Normal file
@ -0,0 +1,12 @@
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
|
||||
rule_files:
|
||||
- 'alert.rules'
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'traefik'
|
||||
scrape_interval: 5s
|
||||
static_configs:
|
||||
- targets: ['dashboard.kaz.sns:8289','dashboard2.kaz.sns:8289']
|
1
dockers/imapsync/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
31
dockers/imapsync/docker-compose.yml
Normal file
@ -0,0 +1,31 @@
|
||||
version: '3.3'
|
||||
|
||||
services:
|
||||
|
||||
imapsync:
|
||||
image: gilleslamiral/imapsync
|
||||
command: /servimapsync
|
||||
container_name: ${imapsyncServName}
|
||||
restart: ${restartPolicy}
|
||||
networks:
|
||||
- imapsyncNet
|
||||
env_file:
|
||||
- ../../secret/env-${imapsyncServName}
|
||||
expose:
|
||||
- 80
|
||||
volumes:
|
||||
- ./imapsync_form_extra.html:/var/tmp/imapsync_form_extra.html
|
||||
- ./imapsync_form.css:/var/tmp/imapsync_form.css
|
||||
#on autorise 40% du cpu : si la machine s' emballe, les ressources seront atteintes et imapsync régulera
|
||||
cpus: 0.4
|
||||
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${imapsyncServName}.rule=Host(`${imapsyncHost}.${domain}`)"
|
||||
- "traefik.http.services.${imapsyncServName}.loadbalancer.server.port=${imapsyncPort}"
|
||||
- "traefik.docker.network=imapsyncNet"
|
||||
|
||||
networks:
|
||||
imapsyncNet:
|
||||
external: true
|
||||
name: imapsyncNet
|
66
dockers/imapsync/imapsync_form.css
Normal file
484
dockers/imapsync/imapsync_form_extra.html
Normal file
@ -0,0 +1,484 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!-- $Id: imapsync_form_extra.html,v 1.29 2024/01/14 19:47:25 gilles Exp gilles $ -->
|
||||
|
||||
<html lang="en" id="top">
|
||||
|
||||
|
||||
<head>
|
||||
<!--
|
||||
<script
|
||||
data-ad-client="ca-pub-3325993554161060"
|
||||
async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
|
||||
</script>
|
||||
-->
|
||||
|
||||
<title>Imapsync Online Unlimited</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!--
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
|
||||
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
||||
-->
|
||||
|
||||
<link rel="stylesheet" href="imapsync_form.css">
|
||||
<link rel="stylesheet" href="../S/style.css" type="text/css" />
|
||||
|
||||
<link rel="license" href="https://imapsync.lamiral.info/NOLIMIT">
|
||||
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="noscript.css">
|
||||
</noscript>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="scripton">
|
||||
<!-- will appear if some tests fail -->
|
||||
<pre id="tests" class="collapse"></pre>
|
||||
<!-- hidden stuff that must exit for the tests -->
|
||||
<div class="hidden">
|
||||
<input type="checkbox" id="test_checkbox">
|
||||
<input type="text" id="test_text">
|
||||
<input type="radio" id="test_radio1" name="test_radio" value="first" >
|
||||
<input type="radio" id="test_radio2" name="test_radio" value="second" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid" >
|
||||
|
||||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home" title="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 class="text-center">Imapsync Online Unlimited</h1>
|
||||
|
||||
<p class="text-center larger"> <strong>Copy</strong>/synchronize a <strong>complete</strong> Mailbox to another, without <strong>duplicates!</strong></p>
|
||||
|
||||
|
||||
<form id="form" action="/cgi-bin/imapsync" method="post" autocomplete="on">
|
||||
<div id="form_row" class="row">
|
||||
<div id="account1" class="col-md-5" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP source Mailbox</legend>
|
||||
|
||||
<label for="user1">Login</label> (usually an email address)
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"> </i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user1" name="user1" tabindex="1"
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
|
||||
<label for="password1">Password</label>
|
||||
<label class="checkbox-inline out">
|
||||
<input type="checkbox" id="showpassword1"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password1" name="password1" tabindex="2"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host1">IMAP Server hostname</label> (or its IP address)
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers1" type="text" class="form-control input-lg" id="host1" name="host1" tabindex="3"
|
||||
placeholder="Enter IMAP source server name or IP address">
|
||||
<datalist id="servers1">
|
||||
<option value="imap.gmail.com">
|
||||
<option value="outlook.office365.com">
|
||||
<option value="imap.hostinger.com">
|
||||
<option value="ssl0.ovh.net">
|
||||
<option value="email-ssl.com.br">
|
||||
<option value="imap.mail.yahoo.com">
|
||||
</datalist>
|
||||
</div>
|
||||
|
||||
<div class="form-group collapse extra_param">
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Be careful with this option"
|
||||
type="checkbox" id="delete1" name="delete1">Move sync. Deletes messages on source mailbox after a successful transfer.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group collapse extra_param" >
|
||||
<label for="subfolder1">Sub-folder</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-folder-open"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="A subfolder where all the source mailbox comes from."
|
||||
type="text" class="form-control input-lg" id="subfolder1" name="subfolder1"
|
||||
placeholder="Enter sub-folder name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div id="parameters" class="col-md-2" >
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Shows what would be done without really doing it."
|
||||
type="checkbox" id="dry" name="dry" >Just verbose, no real sync.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Checks credentials without syncing anything."
|
||||
type="checkbox" id="justlogin" name="justlogin" >Just checks credentials.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Shows folders sizes and exits."
|
||||
type="checkbox" id="justfoldersizes" name="justfoldersizes" >Just presents folders sizes.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Just create the folder hierarchy, messages are not synced."
|
||||
type="checkbox" id="justfolders" name="justfolders" >Just create folders.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div id="button_extra_param" class="text-center scripton">
|
||||
<button type="button" class="btn btn-default btn-block" data-toggle="collapse"
|
||||
data-target=".extra_param">Show / Hide extra parameters</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div id="button_swap" class="text-center scripton">
|
||||
<button type="button" class="btn btn-default btn-block" id="swap">
|
||||
Swap Source <span class="glyphicon glyphicon-transfer"></span> Destination
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="account2" class="col-md-5" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP destination Mailbox</legend>
|
||||
|
||||
<label for="user2">Login</label> (usually an email address)
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user2" name="user2" tabindex="6"
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
<label for="password2">Password</label>
|
||||
<label class="checkbox-inline out">
|
||||
<input type="checkbox" id="showpassword2"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password2" name="password2" tabindex="7"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host2">IMAP Server hostname</label> (or its IP address)
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
|
||||
<select data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it." class="form-control input-lg" id="host2" name="host2">
|
||||
<option value="mail.kaz.bzh">mail.kaz.bzh</option>
|
||||
</select>
|
||||
<!--
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers2" type="text" class="form-control input-lg" id="host2" name="host2" tabindex="8"
|
||||
placeholder="Enter IMAP destination server name or IP address">
|
||||
<datalist id="servers2">
|
||||
<option value="imap.gmail.com">
|
||||
<option value="outlook.office365.com">
|
||||
<option value="imap.hostinger.com">
|
||||
<option value="ssl0.ovh.net">
|
||||
<option value="email-ssl.com.br">
|
||||
<option value="imap.mail.yahoo.com">
|
||||
</datalist>
|
||||
-->
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="form-group collapse extra_param">
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Be careful with this option"
|
||||
type="checkbox" id="delete2" name="delete2" tabindex="9">Strict sync. Deletes messages on destination mailbox that are not at the source mailbox.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group collapse extra_param" id="extra_subfolder2" >
|
||||
<label for="subfolder2">Sub-folder</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-folder-open"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="A subfolder where all the source mailbox will go."
|
||||
type="text" class="form-control input-lg" id="subfolder2" name="subfolder2"
|
||||
placeholder="Enter sub-folder name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- -->
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="automap" value="on">
|
||||
<input type="hidden" name="addheader" value="on">
|
||||
<!-- -#->
|
||||
<input type="hidden" name="simulong" value="360">
|
||||
<!-#- -->
|
||||
|
||||
<a id="buttons"></a>
|
||||
<hr>
|
||||
|
||||
<div class="text-center center-block">
|
||||
If you <b>close</b> this <b>window</b> (or tab) <b>during</b> the synchronization,
|
||||
it will <b>stop</b> the synchronization, it's like <b>hitting</b> the red button <b>"Stop!"</b> below.
|
||||
</div>
|
||||
|
||||
<!-- Classical button to go to the log only, when javascript is turned off -->
|
||||
<noscript>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 padd0" >
|
||||
<button type="submit" class="btn btn-success btn-lg center-block btn-block">Go sync!</button>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<!-- Javascript buttons using xhr -->
|
||||
<div class="row scripton">
|
||||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-sync" type="button"
|
||||
class="btn btn-success btn-lg center-block btn-block"
|
||||
tabindex="11"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Launch the sync! You can stop the sync with the red Stop! button nearby or by closing the tab/window."
|
||||
>
|
||||
Sync or resync!<br>
|
||||
<span class="glyphicon glyphicon-envelope"></span>
|
||||
<span class="glyphicon glyphicon-arrow-right"></span>
|
||||
<span class="glyphicon glyphicon-envelope"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-abort" type="button"
|
||||
class="btn btn-danger btn-lg center-block btn-block" tabindex="12"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Stop the sync! You can restart the sync later, no duplicates should happen."
|
||||
>
|
||||
Stop!<br>
|
||||
<span class="glyphicon glyphicon-scissors"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="row scripton" id="consoles" >
|
||||
|
||||
<pre id="imapsync_current" class="center-block text-center"></pre>
|
||||
|
||||
<span id="imapsync_advice_hours" class="text-center collapse">
|
||||
Best <a href="#local_bandwidth"><b>bandwidth available hours</b></a> are from <b>11h PM to 11h AM UTC</b> on Mondays to Fridays, <b>all hours</b> on Saturdays and <b>Sundays</b>.
|
||||
</span>
|
||||
|
||||
<pre id="progress-txt">ETA: Estimation Time of Arrival</pre>
|
||||
|
||||
<div class="progress">
|
||||
<div id="progress-bar-done" class="progress-bar progress-bar-success" role="progressbar">
|
||||
Progress bar
|
||||
</div>
|
||||
<div id="progress-bar-left" class="progress-bar progress-bar-info" role="progressbar">
|
||||
Progress bar
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 well">
|
||||
<h2 class="text-center">Console of imapsync launch</h2>
|
||||
<pre id="console">
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 well">
|
||||
<h2 class="text-center">Console of Stopping</h2>
|
||||
<pre id="abort">
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 id="imapsync_log_beginning" class="text-center scripton">Log of imapsync run</h2>
|
||||
<div class="text-center scripton">
|
||||
<a href="#imapsync_log_bottom">Link to the <b>bottom</b> of the imapsync log file</a>
|
||||
</div>
|
||||
|
||||
<pre id="output" class="scripton">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
|
||||
<div id="imapsync_log_bottom" class="text-center scripton">
|
||||
<a href="#imapsync_log_beginning">Link to the <b>beginning</b> of the imapsync log file</a>
|
||||
</div>
|
||||
|
||||
<div id="local_bandwidth" class="collapse">
|
||||
<hr>
|
||||
<p class="text-center">
|
||||
<b>Local bandwidth statistics</b><br>
|
||||
|
||||
<a href="/vnstat/vnstati.html">
|
||||
<img alt="Local bandwidth statistics" src="/vnstat/vnstat_vs.png" >
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="local_status_dbmon" class="collapse">
|
||||
<hr>
|
||||
<p class="text-center">
|
||||
Imapsync <b>Online Status</b> over the <b>last 24h</b><br>
|
||||
<a href="imapsync_online_status.html"><img id="status_24h" class="img-responsive center-block" alt="Imapsync Online Status over the last 24h" src="https://sup.lamiral.info/dbmon/cgi-bin/rrdview.cgi?child=yes&rrdfile=%2Fvar%2Ftmp%2Fdbmon%2Ftests%2Frrdbases%2Flocalhost~2583~LAMIRAL~Imapsync_Online~LAMIRAL%2CImapsync_Online~opstatus~300~.rrd;interval_vue=p86400;date_given_by=now;date_means=end;dsname=opstatus;width=1200;hight=70;lower=0;upper=100;rigid=on;Beautiful%20Image%21.x=128;Beautiful%20Image%21.y=30;title=Service%20Status;owner=Imapsync_Online;caption=Status%20in%20%25;monitor=https.rrdrt.monitor%20--rrdrt%20imapsync.lamiral.info%2Fcgi-bin%2Fimapsync%20%3B%3B">
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="local_status_hetrix" class="collapse">
|
||||
<hr>
|
||||
<p class="text-center">
|
||||
|
||||
The service is down? For how long? How often? Take also a look at the
|
||||
<a href="https://hetrixtools.com/report/uptime/873a2356aea43055204b59f562b5ad52/414322.html">Imapsync Online Status</a>
|
||||
monitor page powered by the <a href="https://hetrixtools.com/414322.html">HetrixTools</a> company.
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a id="bottom"></a>
|
||||
<hr>
|
||||
|
||||
<p class="text-center">Feel free to contact
|
||||
<strong><a href="https://imapsync.lamiral.info/#AUTHOR" target="_blank">Gilles LAMIRAL</a></strong>
|
||||
</p>
|
||||
|
||||
|
||||
<div class="container-fluid" >
|
||||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
<br>
|
||||
<small> ($Id: imapsync_form_extra.html,v 1.29 2024/01/14 19:47:25 gilles Exp gilles $) </small><br>
|
||||
Terms and conditions for anything: <a href="https://imapsync.lamiral.info/LICENSE">No limits to do anything with this work and this license!</a><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script
|
||||
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
|
||||
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
|
||||
crossorigin="anonymous"
|
||||
>
|
||||
</script>
|
||||
|
||||
<script
|
||||
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
|
||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"
|
||||
>
|
||||
</script>
|
||||
|
||||
<!--
|
||||
<script src="crypto-js/core.js"></script>
|
||||
<script src="crypto-js/sha256.js"></script>
|
||||
-->
|
||||
|
||||
<script
|
||||
src="imapsync_form.js"
|
||||
>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
1
dockers/jirafeau/.env
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/dockers.env
|
75
dockers/jirafeau/Dockerfile
Normal file
@ -0,0 +1,75 @@
|
||||
FROM php:7.4-apache
|
||||
|
||||
########################################
|
||||
# APT local cache
|
||||
# work around because COPY failed if no source file
|
||||
COPY .dummy .apt-mirror-confi[g] .proxy-confi[g] /
|
||||
RUN cp /.proxy-config /etc/profile.d/proxy.sh 2> /dev/null || true
|
||||
RUN if [ -f /.apt-mirror-config ] ; then . /.apt-mirror-config && sed -i \
|
||||
-e "s%s\?://deb.debian.org%://${APT_MIRROR_DEBIAN}%g" \
|
||||
-e "s%s\?://security.debian.org%://${APT_MIRROR_DEBIAN_SECURITY}%g" \
|
||||
-e "s%s\?://archive.ubuntu.com%://${APT_MIRROR_UBUNTU}%g" \
|
||||
-e "s%s\?://security.ubuntu.com%://${APT_MIRROR_UBUNTU_SECURITY}%g" \
|
||||
/etc/apt/sources.list; fi
|
||||
|
||||
########################################
|
||||
RUN apt-get update --quiet && apt-get install -y \
|
||||
libicu-dev libpq-dev zlib1g-dev libicu-dev \
|
||||
libzip-dev wget zip patch mailutils sendmail
|
||||
|
||||
RUN apt-get install -y emacs php-elisp telnet
|
||||
|
||||
RUN sed -i 's/127.0.0.1/smtp/' /etc/mail/submit.mc
|
||||
RUN echo "define(\`SMART_HOST',\`smtp')" >> /etc/mail/sendmail.mc
|
||||
RUN m4 /etc/mail/submit.mc > /etc/mail/submit.cf
|
||||
RUN m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
|
||||
|
||||
#install composer setup script
|
||||
COPY dockers/jirafeau/composer-setup.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/composer-setup.sh
|
||||
|
||||
#install internationalization libs
|
||||
RUN docker-php-ext-configure intl
|
||||
RUN docker-php-ext-install intl
|
||||
RUN docker-php-ext-install zip
|
||||
|
||||
########################################
|
||||
#install jirafeau
|
||||
RUN mkdir /var/jirafeau/ /var/jirafeauData/
|
||||
WORKDIR /var/jirafeau
|
||||
COPY --chown=www-data git/Jirafeau/ .
|
||||
COPY --chown=www-data git/depollueur/src/Jirafeau/[aft].php ./
|
||||
COPY --chown=www-data dockers/jirafeau/media/kaz media/kaz
|
||||
RUN sed -i -e '1i\<p>La limite des téléversements est actuellement de <?php echo ini_get("post_max_size"); ?></p>' lib/template/footer.php
|
||||
RUN sed -i -e '/<div id="jyraphe">/i\<div id="kaz">' lib/template/footer.php
|
||||
|
||||
COPY dockers/jirafeau/config/composer.json .
|
||||
RUN /usr/local/bin/composer-setup.sh
|
||||
RUN php composer.phar install
|
||||
|
||||
RUN echo '\n\
|
||||
upload_max_filesize = 1024M\n\
|
||||
post_max_size = 1024M\n\
|
||||
[mail function]\n\
|
||||
SMTP = smtp\n\
|
||||
smtp_port = 25\n\
|
||||
sendmail_path=/usr/sbin/sendmail -t -i\n\
|
||||
sendmail_from = no-reply@kaz.local\n\
|
||||
' > /usr/local/etc/php/php.ini
|
||||
|
||||
RUN chown -R www-data.www-data . /var/jirafeauData/
|
||||
RUN chmod o=,ug=rwX -R . /var/jirafeauData/
|
||||
RUN rm -rf .git .gitignore .gitlab-ci.yml CONTRIBUTING.md README.md Dockerfile
|
||||
|
||||
VOLUME ["/var/jirafeauData", "/etc/apache2/sites-available"]
|
||||
|
||||
RUN echo "#!/bin/sh" >> /entrypoint.sh
|
||||
RUN echo "chown -R www-data: /var/jirafeauData/" >> /entrypoint.sh
|
||||
RUN echo "/usr/sbin/apache2ctl -D FOREGROUND" >> /entrypoint.sh
|
||||
RUN chmod u=+x /entrypoint.sh
|
||||
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
32
dockers/jirafeau/build.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
SERV_DIR=$(cd $(dirname $0); pwd)
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
cd "${SERV_DIR}"
|
||||
CONF_FILE="config/config.local.php"
|
||||
touch "${CONF_FILE}"
|
||||
chown 33:33 "${CONF_FILE}"
|
||||
|
||||
SRC_JIR="https://gitlab.com/mojo42/Jirafeau.git"
|
||||
JIR_VER="4.3.0"
|
||||
|
||||
"${KAZ_BIN_DIR}/installDepollueur.sh"
|
||||
|
||||
printKazMsg "\n *** Création du Dockerfile Jirafeau"
|
||||
|
||||
printKazMsg "\n - GIT Jirafeau "
|
||||
cd "${KAZ_GIT_DIR}"
|
||||
if [ ! -d "Jirafeau" ]; then
|
||||
git clone "${SRC_JIR}" --branch ${JIR_VER}
|
||||
fi
|
||||
|
||||
cd "${KAZ_GIT_DIR}/Jirafeau" && git reset --hard && git checkout ${JIR_VER}
|
||||
|
||||
printKazMsg "\n - Dockefile"
|
||||
cd "${KAZ_ROOT}"
|
||||
# Pour permettre la copy de git il faut que le répertoire soit visible de la racine qui lance la construction
|
||||
docker build -t filekaz . -f dockers/jirafeau/Dockerfile
|
||||
|
18
dockers/jirafeau/composer-setup.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig)
|
||||
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
|
||||
|
||||
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
|
||||
then
|
||||
>&2 echo 'ERROR: Invalid installer signature'
|
||||
rm composer-setup.php
|
||||
exit 1
|
||||
fi
|
||||
|
||||
php composer-setup.php --quiet
|
||||
RESULT=$?
|
||||
rm composer-setup.php
|
||||
exit $RESULT
|
||||
|
5
dockers/jirafeau/config/composer.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"require": {
|
||||
"phpmailer/phpmailer": "^6.5"
|
||||
}
|
||||
}
|
24
dockers/jirafeau/config/jirafeau.conf
Normal file
@ -0,0 +1,24 @@
|
||||
<VirtualHost *:80>
|
||||
ServerName file.kaz.bzh
|
||||
DocumentRoot /var/jirafeau/
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
ServerSignature Off
|
||||
|
||||
<Location / >
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
Options FollowSymLinks MultiViews
|
||||
<IfModule mod_dav.c>
|
||||
Dav off
|
||||
</IfModule>
|
||||
</Location>
|
||||
|
||||
<FilesMatch "^\.ht.*">
|
||||
deny from all
|
||||
satisfy all
|
||||
ErrorDocument 403 "Access denied."
|
||||
</FilesMatch>
|
||||
|
||||
</VirtualHost>
|
||||
|
44
dockers/jirafeau/docker-compose.yml
Normal file
@ -0,0 +1,44 @@
|
||||
# jirafeauDir doit être déclaré dans .env qui pointe sur ../../config/docker.env
|
||||
# car les variables déclarées dans env_file: ne sont pas encore connues dans volumes:
|
||||
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
jirafeau:
|
||||
image: filekaz
|
||||
build: .
|
||||
container_name: ${jirafeauServName}
|
||||
restart: always
|
||||
networks:
|
||||
- jirafeauNet
|
||||
- postfixNet
|
||||
external_links:
|
||||
- ${smtpServName}:${smtpHost}
|
||||
# ports:
|
||||
# - 8081:80
|
||||
env_file:
|
||||
- ../../secret/env-${jirafeauServName}
|
||||
volumes:
|
||||
- ./config/jirafeau.conf:/etc/apache2/sites-available/000-default.conf
|
||||
- fileData:${jirafeauDir}
|
||||
- ./config/config.local.php:/var/jirafeau/lib/config.local.php
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${jirafeauServName}-admin.rule=Host(`${fileHost}.${domain}`) && PathPrefix(`/admin.php`)"
|
||||
- "traefik.http.routers.${jirafeauServName}-admin.middlewares=test-adminipwhitelist@file"
|
||||
- "traefik.http.routers.${jirafeauServName}.rule=Host(`${fileHost}.${domain}`) && ! PathPrefix(`/admin.php`)"
|
||||
- "traefik.docker.network=jirafeauNet"
|
||||
|
||||
volumes:
|
||||
fileData:
|
||||
config:
|
||||
|
||||
networks:
|
||||
jirafeauNet:
|
||||
external: true
|
||||
name: jirafeauNet
|
||||
postfixNet:
|
||||
external: true
|
||||
name: postfixNet
|
25
dockers/jirafeau/download.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
SERV_DIR=$(cd $(dirname $0); pwd)
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
SRC_JIR="https://gitlab.com/mojo42/Jirafeau.git"
|
||||
JIR_VER="4.5.0"
|
||||
|
||||
printKazMsg "\n *** Download Jirafeau"
|
||||
|
||||
mkdir -p "${KAZ_GIT_DIR}"
|
||||
cd "${KAZ_GIT_DIR}"
|
||||
if [ ! -d "Jirafeau" ]; then
|
||||
git clone "${SRC_JIR}" --branch ${JIR_VER}
|
||||
fi
|
||||
|
||||
cd "${KAZ_GIT_DIR}/Jirafeau"
|
||||
if [ -z "$(git branch | grep "${JIR_VER}")" ]; then
|
||||
printKazMsg " checkout branch ${JIR_VER}"
|
||||
git fetch -a
|
||||
git reset --hard
|
||||
git checkout ${JIR_VER}
|
||||
fi
|
50
dockers/jirafeau/first.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
|
||||
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
|
||||
setKazVars
|
||||
|
||||
JIR_VER=4.5.0
|
||||
|
||||
cd $(dirname $0)
|
||||
. "${DOCKERS_ENV}"
|
||||
. "${KAZ_KEY_DIR}/env-${jirafeauServName}"
|
||||
|
||||
CONF_FILE="${DOCK_VOL}/jirafeau_config/_data/config.local.php"
|
||||
|
||||
if ! grep -q "'installation_done'\s*=>\s*true" "${CONF_FILE}" 2>/dev/null ; then
|
||||
printKazMsg "\n *** Premier lancement de Jirafeau"
|
||||
|
||||
checkDockerRunning "${jirafeauServName}" "Jirafeau" || exit
|
||||
curl -X POST \
|
||||
-d "jirafeau=${JIR_VER}" \
|
||||
-d "step=1" \
|
||||
-d "admin_password=${HTTPD_PASSWORD}" \
|
||||
-d "next=1" \
|
||||
"${httpProto}://${fileHost}.${domain}/install.php"
|
||||
curl -X POST -d "jirafeau=${JIR_VER}" \
|
||||
-d "step=2" \
|
||||
-d "web_root=${httpProto}://${fileHost}.${domain}/" \
|
||||
-d "var_root=${jirafeauDir}" \
|
||||
-d "next=1" \
|
||||
"${httpProto}://${fileHost}.${domain}/install.php"
|
||||
fi
|
||||
|
||||
updatePhpVar(){
|
||||
# $1 key
|
||||
# $2 val
|
||||
# $3 file
|
||||
if grep -q "$1" "$3" ; then
|
||||
sed -i \
|
||||
-e "s%\([\"']$1[\"']\s*=>\s*\)[^,]*,%\1$2,%" \
|
||||
"$3"
|
||||
fi
|
||||
}
|
||||
|
||||
updatePhpVar "style" "'kaz'" "${CONF_FILE}"
|
||||
updatePhpVar "organisation" "'KAZ'" "${CONF_FILE}"
|
||||
|
||||
#updatePhpVar "web_root" "'${httpProto}://${fileHost}.${domain}/'" "${CONF_FILE}"
|
||||
#updatePhpVar "admin_password" "'$(echo -n "${HTTPD_PASSWORD}" | sha256sum | awk '{print $1}')'" "${CONF_FILE}"
|
||||
#updatePhpVar "var_root" "'${jirafeauDir}'" "${CONF_FILE}"
|
||||
#updatePhpVar "installation_done" "true" "${CONF_FILE}"
|
BIN
dockers/jirafeau/media/kaz/bandeau.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
dockers/jirafeau/media/kaz/email.png
Normal file
After Width: | Height: | Size: 596 B |
BIN
dockers/jirafeau/media/kaz/error.png
Normal file
After Width: | Height: | Size: 525 B |
BIN
dockers/jirafeau/media/kaz/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
dockers/jirafeau/media/kaz/jyraphe.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
dockers/jirafeau/media/kaz/kaz.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
dockers/jirafeau/media/kaz/ok.png
Normal file
After Width: | Height: | Size: 492 B |
205
dockers/jirafeau/media/kaz/style.css.php
Normal file
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/*
|
||||
* Jyraphe, your web file repository
|
||||
* Copyright (C) 2008 Julien "axolotl" BERNARD <axolotl@magieeternelle.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This stylesheet is the default stylesheet for Jyraphe.
|
||||
* The content is dynamically generated for easier handling.
|
||||
*/
|
||||
|
||||
$dark = '#8B4513';
|
||||
|
||||
header('Content-type: text/css');
|
||||
|
||||
?>
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
margin: 2ex auto;
|
||||
background: white;
|
||||
/* border: <?php echo $dark; ?> 5px solid; */
|
||||
}
|
||||
|
||||
fieldset {
|
||||
text-align: left;
|
||||
width: 40em;
|
||||
margin: auto;
|
||||
background: #E2f5ff;
|
||||
border: 2px solid #02233f;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
color: white;
|
||||
background: #02233f;
|
||||
border: 2px solid #02233f;
|
||||
padding: 1px 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
background: url('bandeau.png') left top repeat-x;
|
||||
height: 70px;
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
h1 a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
fieldset p {
|
||||
margin-left: 25%;
|
||||
}
|
||||
|
||||
.jyraphe_info {
|
||||
font-size: small;
|
||||
margin-left: 30%;
|
||||
}
|
||||
|
||||
label {
|
||||
float: left;
|
||||
width: 12em;
|
||||
}
|
||||
|
||||
input[type=text], input[type=submit], select {
|
||||
color: black;
|
||||
width: 15em;
|
||||
border: 1px #02233f solid;
|
||||
background: white;
|
||||
}
|
||||
|
||||
input:hover {
|
||||
color: white;
|
||||
background: #02233f;
|
||||
}
|
||||
|
||||
#jyraphe {
|
||||
background: url('jyraphe.png') right bottom no-repeat;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
#kaz {
|
||||
background: url('kaz.png') right bottom no-repeat;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 10px;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
#copyright {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.error, .message {
|
||||
width: 50em;
|
||||
margin: 5ex auto;
|
||||
}
|
||||
|
||||
.error {
|
||||
padding-bottom: 1ex;
|
||||
border: red 2px solid;
|
||||
background-color: #FBB;
|
||||
}
|
||||
|
||||
.error p:before {
|
||||
content: url('error.png');
|
||||
padding-right: 1ex;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 1ex;
|
||||
border: green 2px solid;
|
||||
background-color: #BFB;
|
||||
}
|
||||
|
||||
.message p:before {
|
||||
content: url('ok.png');
|
||||
padding-right: 1ex;
|
||||
}
|
||||
|
||||
.info {
|
||||
text-align: left;
|
||||
width: 40em;
|
||||
margin: auto;
|
||||
background: #E2f5ff;
|
||||
border: 2px solid #02233f;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.info h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info h3 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info p {
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
#upload {}
|
||||
|
||||
#uploading {
|
||||
text-align: center;
|
||||
width: 30em;
|
||||
background: #E2f5ff;
|
||||
border: 2px solid #02233f;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#upload_finished {
|
||||
text-align: center;
|
||||
width: 60em;
|
||||
background: #E2f5ff;
|
||||
border: 2px solid #02233f;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#self_destruct {
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
}
|
||||
|
||||
#upload_link_email {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#upload_image_email {
|
||||
padding-left: 20px;
|
||||
padding-bottom: 15px;
|
||||
background: url(email.png) no-repeat;
|
||||
}
|