├── auto_update ├── auto_update_config_example.sh └── auto_update.sh ├── conf ├── create_admin.json ├── seafdav.conf ├── gunicorn.conf.py ├── seafile-doc_env.j2 ├── seafevents.conf ├── seafile_env.j2 ├── seafile-notification_env.j2 ├── f2b_filter.conf ├── f2b_jail.conf ├── seafile.conf ├── seafile-thumbnail_env.j2 ├── seafile-notification.service ├── seafile-thumbnail.service ├── seafile-doc-converter.service ├── seafile-doc-server.service ├── seahub.service ├── seafile.service ├── nginx.conf └── seahub_settings.py ├── doc ├── PRE_UPGRADE.d │ └── 13.0.8~ynh1.md ├── screenshots │ └── screenshot.png ├── POST_UPGRADE.md ├── DESCRIPTION.md ├── DESCRIPTION_fr.md └── ADMIN.md ├── sources ├── exec_in_seafile_image.sh ├── exec_in_seafile_notification_image.sh ├── exec_in_thumbnail_image.sh └── exec_in_seadoc_image.sh ├── .gitattributes ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── LICENSE ├── scripts ├── backup ├── remove ├── change_url ├── restore ├── install ├── _common.sh ├── ynh_setup_source └── upgrade ├── README.md ├── tests.toml ├── .gitignore ├── manifest.toml └── patches └── main └── import_ldap_user_when_authenticated_from_remoteUserBackend.patch /auto_update/auto_update_config_example.sh: -------------------------------------------------------------------------------- 1 | notify_email="hello@world.tld" 2 | -------------------------------------------------------------------------------- /conf/create_admin.json: -------------------------------------------------------------------------------- 1 | {"email": "__ADMIN__", "password": "__PASSWORD__"} 2 | -------------------------------------------------------------------------------- /doc/PRE_UPGRADE.d/13.0.8~ynh1.md: -------------------------------------------------------------------------------- 1 | - Upgrade to seafile 13 (major update) 2 | - Add seadoc -------------------------------------------------------------------------------- /conf/seafdav.conf: -------------------------------------------------------------------------------- 1 | [WEBDAV] 2 | enabled = true 3 | port = __PORT_WEBDAV__ 4 | share_name = /seafdav 5 | -------------------------------------------------------------------------------- /doc/screenshots/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YunoHost-Apps/seafile_ynh/HEAD/doc/screenshots/screenshot.png -------------------------------------------------------------------------------- /doc/POST_UPGRADE.md: -------------------------------------------------------------------------------- 1 | Since seafile 12, for security reason, WebDAV no longer support login with LDAP account, the user with LDAP account must generate a WebDAV token at the profile page. 2 | -------------------------------------------------------------------------------- /doc/DESCRIPTION.md: -------------------------------------------------------------------------------- 1 | Seafile is an open Source Cloud Storage application. 2 | 3 | It's a Enterprise file sync and share platform with high reliability and performance. It's a file hosting platform with high reliability and performance. Put files on your own server. Sync and share files across different devices, or access all the files as a virtual disk. 4 | -------------------------------------------------------------------------------- /doc/DESCRIPTION_fr.md: -------------------------------------------------------------------------------- 1 | Seafile est une application open source dédiée au stockage de fichiers en nuage. 2 | 3 | Cette plateforme d'entreprise permet de synchroniser et partager des fichiers, de façon fiable et performante. Hébergez vos fichiers sur un serveur personnel, partagez-les et syncronisez-les sur tous appareils, ou accédez à vos fichiers par le biais d'un disque virtuel. 4 | -------------------------------------------------------------------------------- /sources/exec_in_seafile_image.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | set -eu 4 | 5 | readonly app="{{ app }}" 6 | readonly install_dir="{{ install_dir }}" 7 | readonly systemd_seafile_bind_mount="{{ systemd_seafile_bind_mount }}" 8 | 9 | mkdir -p "/run/$app/pids" 10 | systemd-run --wait --pipe --uid="$app" --gid="$app" \ 11 | --property=RootDirectory="$install_dir"/seafile_image \ 12 | --property="BindPaths=$systemd_seafile_bind_mount" \ 13 | --property=EnvironmentFile="$install_dir"/seafile_env.conf \ 14 | "$@" 15 | -------------------------------------------------------------------------------- /conf/gunicorn.conf.py: -------------------------------------------------------------------------------- 1 | # WARNING: Don't edit this file. All change will be removed after each app upgrade 2 | 3 | import os 4 | 5 | daemon = True 6 | workers = 5 7 | enable_stdio_inheritance = True 8 | 9 | # default localhost:8000 10 | bind = "127.0.0.1:__PORT_SEAHUB__" 11 | 12 | # Pid 13 | pids_dir = '/opt/seafile/pids' 14 | pidfile = os.path.join(pids_dir, 'seahub.pid') 15 | 16 | # for file upload, we need a longer timeout value (default is only 30s, too short) 17 | timeout = 1200 18 | 19 | limit_request_line = 8190 20 | -------------------------------------------------------------------------------- /conf/seafile-doc_env.j2: -------------------------------------------------------------------------------- 1 | TIME_ZONE={{ time_zone }} 2 | JWT_PRIVATE_KEY={{ jwt_private }} 3 | 4 | # Database 5 | DB_HOST=127.0.0.1 6 | DB_PORT=3306 7 | DB_USER={{ db_user }} 8 | DB_PASSWORD={{ db_pwd }} 9 | DB_NAME=seahubdb 10 | 11 | SEAHUB_SERVICE_URL=https://{{ domain }}{{ path2 }} 12 | 13 | SDOC_SERVER_CONFIG=/opt/sdoc-server/conf/sdoc_server_config.json 14 | CONF_PATH=/opt/sdoc-server/conf/ 15 | LOG_DIR=/opt/sdoc-server/logs/ 16 | SDOC_SERVER_DIR=/opt/sdoc-server/sdoc-server-latest/sdoc-server 17 | SERVER_PORT = {{ port_seadoc }} 18 | -------------------------------------------------------------------------------- /sources/exec_in_seafile_notification_image.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | set -eu 4 | 5 | readonly app="{{ app }}" 6 | readonly install_dir="{{ install_dir }}" 7 | readonly systemd_notification_server_bind_mount="{{ systemd_notification_server_bind_mount }}" 8 | 9 | mkdir -p "/run/$app/pids" 10 | systemd-run --wait --pipe --uid="$app" --gid="$app" \ 11 | --property=RootDirectory="$install_dir"/seafile_image \ 12 | --property="BindPaths=$systemd_notification_server_bind_mount" \ 13 | --property=EnvironmentFile="$install_dir"/notification_server_env.conf \ 14 | "$@" 15 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /conf/seafevents.conf: -------------------------------------------------------------------------------- 1 | # WARNING: Don't edit this file. All change will be removed after each app upgrade 2 | 3 | [DATABASE] 4 | type = mysql 5 | host = 127.0.0.1 6 | port = 3306 7 | username = __DB_USER__ 8 | password = __DB_PWD__ 9 | name = seahubdb 10 | 11 | [STATISTICS] 12 | ## must be "true" to enable statistics 13 | enabled = false 14 | 15 | [SEAHUB EMAIL] 16 | ## must be "true" to enable user email notifications when there are new unread notifications 17 | enabled = true 18 | 19 | ## interval of sending Seahub email. Can be s(seconds), m(minutes), h(hours), d(days) 20 | interval = 1d 21 | -------------------------------------------------------------------------------- /sources/exec_in_thumbnail_image.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | set -eu 4 | 5 | readonly app="{{ app }}" 6 | readonly install_dir="{{ install_dir }}" 7 | readonly systemd_thumbnail_bind_mount="{{ systemd_thumbnail_bind_mount }}" 8 | 9 | mkdir -p "/run/$app/pids" 10 | systemd-run --wait --pipe --uid="$app" --gid="$app" \ 11 | --property=RootDirectory="$install_dir"/seafile_image \ 12 | --property="BindPaths=$systemd_thumbnail_bind_mount" \ 13 | --property=EnvironmentFile="$install_dir"/seafile_env.conf \ 14 | --property=WorkingDirectory=/opt/seafile/thumbnail-server \ 15 | "$@" 16 | -------------------------------------------------------------------------------- /sources/exec_in_seadoc_image.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | set -eu 4 | 5 | readonly app="{{ app }}" 6 | readonly install_dir="{{ install_dir }}" 7 | readonly systemd_seadoc_bind_mount="{{ systemd_seadoc_bind_mount }}" 8 | 9 | mkdir -p "/run/$app/pids" 10 | systemd-run --wait --pipe --uid="$app" --gid="$app" \ 11 | --property=RootDirectory="$install_dir"/seafile_image \ 12 | --property="BindPaths=$systemd_seadoc_bind_mount" \ 13 | --property=EnvironmentFile="$install_dir"/seadoc_env.conf \ 14 | --property=WorkingDirectory=/opt/sdoc-server/sdoc-server-latest/sdoc-server \ 15 | "$@" 16 | -------------------------------------------------------------------------------- /conf/seafile_env.j2: -------------------------------------------------------------------------------- 1 | TIME_ZONE={{ time_zone }} 2 | JWT_PRIVATE_KEY={{ jwt_private }} 3 | SITE_ROOT={{ path2 }} 4 | 5 | SEAFILE_SERVER_PROTOCOL=https 6 | SEAFILE_SERVER_HOSTNAME={{ domain }} 7 | 8 | # Database 9 | SEAFILE_MYSQL_DB_HOST=127.0.0.1 10 | SEAFILE_MYSQL_DB_PORT=3306 11 | SEAFILE_MYSQL_DB_USER={{ db_user }} 12 | SEAFILE_MYSQL_DB_PASSWORD={{ db_pwd }} 13 | SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnetdb 14 | SEAFILE_MYSQL_DB_SEAFILE_DB_NAME={{ db_name }} 15 | SEAFILE_MYSQL_DB_SEAHUB_DB_NAME=seahubdb 16 | 17 | # Seadoc 18 | ENABLE_SEADOC=true 19 | SEADOC_SERVER_URL=https://{{ domain }}{{ path2 }}sdoc 20 | -------------------------------------------------------------------------------- /conf/seafile-notification_env.j2: -------------------------------------------------------------------------------- 1 | TIME_ZONE={{ time_zone }} 2 | JWT_PRIVATE_KEY={{ jwt_private }} 3 | 4 | SEAFILE_SERVER_PROTOCOL=https 5 | SEAFILE_SERVER_HOSTNAME={{ domain }} 6 | 7 | # Database 8 | SEAFILE_MYSQL_DB_HOST=127.0.0.1 9 | SEAFILE_MYSQL_DB_PORT=3306 10 | SEAFILE_MYSQL_DB_USER={{ db_user }} 11 | SEAFILE_MYSQL_DB_PASSWORD={{ db_pwd }} 12 | SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnetdb 13 | SEAFILE_MYSQL_DB_SEAFILE_DB_NAME={{ db_name }} 14 | 15 | # Notification server 16 | SEAFILE_LOG_TO_STDOUT=true 17 | NOTIFICATION_SERVER_LOG_LEVEL=info 18 | NOTIFICATION_SERVER_HOST=127.0.0.1 19 | NOTIFICATION_SERVER_PORT={{ port_notificationserver }} 20 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Problem 2 | 3 | - *Description of why you made this PR* 4 | 5 | ## Solution 6 | 7 | - *And how do you fix that problem* 8 | 9 | ## PR Status 10 | 11 | - [ ] Code finished and ready to be reviewed/tested 12 | - [ ] The fix/enhancement were manually tested (if applicable) 13 | 14 | ## Automatic tests 15 | 16 | Automatic tests can be triggered on https://ci-apps-dev.yunohost.org/ *after creating the PR*, by commenting "!testme", "!gogogadgetoci" or "By the power of systemd, I invoke The Great App CI to test this Pull Request!". (N.B. : for this to work you need to be a member of the Yunohost-Apps organization) 17 | -------------------------------------------------------------------------------- /conf/f2b_filter.conf: -------------------------------------------------------------------------------- 1 | # Fail2Ban filter for seafile 2 | # 3 | 4 | [INCLUDES] 5 | 6 | # Read common prefixes. If any customizations available -- read them from 7 | # common.local 8 | before = common.conf 9 | 10 | [Definition] 11 | 12 | _daemon = seaf-server 13 | 14 | failregex = Login attempt limit reached.*, ip: 15 | 16 | ignoreregex = 17 | 18 | # DEV Notes: 19 | # 20 | # pattern : 2015-10-20 15:20:32,402 [WARNING] seahub.auth.views:155 login Login attempt limit reached, username: , ip: 1.2.3.4, attemps: 3 21 | # 2015-10-20 17:04:32,235 [WARNING] seahub.auth.views:163 login Login attempt limit reached, ip: 1.2.3.4, attempts: 3 22 | -------------------------------------------------------------------------------- /conf/f2b_jail.conf: -------------------------------------------------------------------------------- 1 | # All standard jails are in the file configuration located 2 | # /etc/fail2ban/jail.conf 3 | 4 | # Warning you may override any other parameter (e.g. banaction, 5 | # action, port, logpath, etc) in that section within jail.local 6 | 7 | # Change logpath with your file log used by seafile (e.g. seahub.log) 8 | # Also you can change the max retry var (3 attemps = 1 line written in the 9 | # seafile log) 10 | # So with this maxrety to 1, the user can try 3 times before his IP is banned 11 | 12 | [seafile] 13 | 14 | enabled = true 15 | port = http,https 16 | filter = seafile 17 | logpath = __INSTALL_DIR__/logs/seahub.log 18 | maxretry = 3 19 | -------------------------------------------------------------------------------- /conf/seafile.conf: -------------------------------------------------------------------------------- 1 | # WARNING: Don't edit this file. All change will be removed after each app upgrade 2 | 3 | [fileserver] 4 | port = __PORT_FILESERVER__ 5 | 6 | # Set maximum upload file size to 200M. 7 | max_upload_size=1000 8 | 9 | # Set maximum download directory size to 200M. 10 | max_download_dir_size=1000 11 | 12 | use_go_fileserver = true 13 | 14 | [database] 15 | type = mysql 16 | host = 127.0.0.1 17 | port = 3306 18 | user = __DB_USER__ 19 | password = __DB_PWD__ 20 | db_name = __DB_NAME__ 21 | connection_charset = utf8 22 | 23 | [memcached] 24 | memcached_options = --SERVER=127.0.0.1 --POOL-MIN=10 --POOL-MAX=100 25 | 26 | [notification] 27 | enabled = true 28 | host = 127.0.0.1 29 | port = __PORT_NOTIFICATIONSERVER__ 30 | log_level = info 31 | jwt_private_key = __JWT_PRIVATE__ 32 | -------------------------------------------------------------------------------- /conf/seafile-thumbnail_env.j2: -------------------------------------------------------------------------------- 1 | TIME_ZONE={{ time_zone }} 2 | JWT_PRIVATE_KEY={{ jwt_private }} 3 | SITE_ROOT={{ path2 }} 4 | 5 | # Database 6 | SEAFILE_MYSQL_DB_HOST=127.0.0.1 7 | SEAFILE_MYSQL_DB_PORT=3306 8 | SEAFILE_MYSQL_DB_USER={{ db_user }} 9 | SEAFILE_MYSQL_DB_PASSWORD={{ db_pwd }} 10 | SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnetdb 11 | SEAFILE_MYSQL_DB_SEAFILE_DB_NAME={{ db_name }} 12 | 13 | SRC_DIR=/opt/seafile/ 14 | LD_LIBRARY_PATH=/opt/seafile/seafile/lib/ 15 | PYTHONPATH=/opt/seafile/seafile/lib/python3/site-packages/:/usr/lib/python3.12/dist-packages:/usr/lib/python3.12/site-packages:/usr/local/lib/python3.12/dist-packages:/usr/local/lib/python3.12/site-packages 16 | PATH=/opt/seafile/seafile/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 17 | 18 | SEAFILE_CONF_DIR=/opt/seafile/seafile-data 19 | SEAFILE_CENTRAL_CONF_DIR=/opt/seafile/conf 20 | CONF_DIR=/opt/seafile/conf 21 | LOG_DIR=/opt/seafile/logs 22 | THUMBNAIL_ROOT=/opt/seafile/seahub-data/thumbnail 23 | 24 | INNER_SEAHUB_SERVICE_URL=https://{{ domain }}{{ path2 }} 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 tostaki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /doc/ADMIN.md: -------------------------------------------------------------------------------- 1 | ### Multi-users support 2 | 3 | This app support LDAP and the SSO authentification. 4 | 5 | If you have Seafile installed before 7.x and you have more than one domain for users in Yunohost or Seafile app is installed on a different domain, you need to migrate your accounts. 6 | You can use the provided action at https://domain.tld/yunohost/admin/#/apps/seafile/actions. You can also use this following command to migrate all of your accounts: 7 | ``` 8 | yunohost app action run seafile migrate_user_email_to_mail_email 9 | ``` 10 | See [issue#44](https://github.com/YunoHost-Apps/seafile_ynh/issues/44) 11 | for more information. 12 | 13 | ### Backup 14 | 15 | This app use now the core-only feature of the backup. To keep the integrity of the data and to have a better guarantee of the restoration is recommended to proceed like this: 16 | 17 | - Stop seafile service with theses following command: 18 | 19 | `systemctl stop seafile.service seahub.service` 20 | 21 | - Launch the backup of seafile with this following command: 22 | 23 | `yunohost backup create --app seafile` 24 | 25 | - Do a backup of your data with your specific strategy (could be with rsync, borg backup or just cp). The data is stored in `/home/yunohost.app/seafile`. 26 | - Restart the seafile service with theses command: 27 | 28 | `systemctl start seafile.service seahub.service` 29 | -------------------------------------------------------------------------------- /conf/seafile-notification.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seafile notification server 3 | After=network.target mysql.service seafile.service 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/opt/seafile/notification-server -c /opt/notification-data 8 | User=__APP__ 9 | Group=__APP__ 10 | 11 | # Config related to run in docker provided file system 12 | RootDirectory=__NOTIFICATION_IMAGE__ 13 | BindPaths=__SYSTEMD_NOTIFICATION_SERVER_BIND_MOUNT__ 14 | EnvironmentFile=__INSTALL_DIR__/notification_server_env.conf 15 | 16 | # Sandboxing options to harden security 17 | # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html 18 | NoNewPrivileges=yes 19 | PrivateTmp=yes 20 | PrivateDevices=yes 21 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 22 | RestrictNamespaces=yes 23 | RestrictRealtime=yes 24 | DevicePolicy=closed 25 | ProtectSystem=full 26 | ProtectControlGroups=yes 27 | ProtectKernelModules=yes 28 | ProtectKernelTunables=yes 29 | LockPersonality=yes 30 | SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap 31 | 32 | # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html 33 | CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD 34 | CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE 35 | CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT 36 | CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK 37 | CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM 38 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG 39 | CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE 40 | CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW 41 | CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG 42 | 43 | [Install] 44 | WantedBy=multi-user.target 45 | -------------------------------------------------------------------------------- /conf/seafile-thumbnail.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seafile thumbnail server 3 | After=network.target mysql.service seafile.service 4 | 5 | [Service] 6 | Type=simple 7 | WorkingDirectory=/opt/seafile/thumbnail-server 8 | ExecStart=/usr/bin/python3 main.py 9 | User=__APP__ 10 | Group=__APP__ 11 | 12 | # Config related to run in docker provided file system 13 | RootDirectory=__THUMBNAIL_SERVER_IMAGE__ 14 | BindPaths=__SYSTEMD_THUMBNAIL_BIND_MOUNT__ 15 | EnvironmentFile=__INSTALL_DIR__/thumbnail_env.conf 16 | 17 | # Sandboxing options to harden security 18 | # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html 19 | NoNewPrivileges=yes 20 | PrivateTmp=yes 21 | PrivateDevices=yes 22 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 23 | RestrictNamespaces=yes 24 | RestrictRealtime=yes 25 | DevicePolicy=closed 26 | ProtectSystem=full 27 | ProtectControlGroups=yes 28 | ProtectKernelModules=yes 29 | ProtectKernelTunables=yes 30 | LockPersonality=yes 31 | SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap 32 | 33 | # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html 34 | CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD 35 | CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE 36 | CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT 37 | CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK 38 | CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM 39 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG 40 | CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE 41 | CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW 42 | CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG 43 | 44 | [Install] 45 | WantedBy=multi-user.target 46 | -------------------------------------------------------------------------------- /conf/seafile-doc-converter.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seadoc server 3 | After=network.target mysql.service seafile.service 4 | 5 | [Service] 6 | Type=simple 7 | WorkingDirectory=/opt/sdoc-server/sdoc-server-latest/seadoc-converter 8 | ExecStart=/usr/bin/python3 -u seadoc_converter/main.py 9 | User=__APP__ 10 | Group=__APP__ 11 | 12 | # Config related to run in docker provided file system 13 | RootDirectory=__SEADOC_IMAGE__ 14 | BindPaths=__SYSTEMD_SEADOC_BIND_MOUNT__ 15 | EnvironmentFile=__INSTALL_DIR__/seadoc_env.conf 16 | 17 | # Sandboxing options to harden security 18 | # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html 19 | NoNewPrivileges=yes 20 | PrivateTmp=yes 21 | PrivateDevices=yes 22 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 23 | RestrictNamespaces=yes 24 | RestrictRealtime=yes 25 | DevicePolicy=closed 26 | ProtectSystem=full 27 | ProtectControlGroups=yes 28 | ProtectKernelModules=yes 29 | ProtectKernelTunables=yes 30 | LockPersonality=yes 31 | SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap 32 | 33 | # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html 34 | CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD 35 | CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE 36 | CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT 37 | CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK 38 | CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM 39 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG 40 | CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE 41 | CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW 42 | CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG 43 | 44 | [Install] 45 | WantedBy=multi-user.target 46 | -------------------------------------------------------------------------------- /conf/seafile-doc-server.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seadoc server 3 | After=network.target mysql.service seafile.service 4 | 5 | [Service] 6 | Type=simple 7 | WorkingDirectory=/opt/sdoc-server/sdoc-server-latest/sdoc-server 8 | ExecStart=/usr/bin/nodejs --max-old-space-size=4096 ./dist/_bin/www.js 9 | User=__APP__ 10 | Group=__APP__ 11 | 12 | # Config related to run in docker provided file system 13 | RootDirectory=__SEADOC_IMAGE__ 14 | BindPaths=__SYSTEMD_SEADOC_BIND_MOUNT__ 15 | EnvironmentFile=__INSTALL_DIR__/seadoc_env.conf 16 | 17 | # Sandboxing options to harden security 18 | # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html 19 | NoNewPrivileges=yes 20 | PrivateTmp=yes 21 | PrivateDevices=yes 22 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 23 | RestrictNamespaces=yes 24 | RestrictRealtime=yes 25 | DevicePolicy=closed 26 | ProtectSystem=full 27 | ProtectControlGroups=yes 28 | ProtectKernelModules=yes 29 | ProtectKernelTunables=yes 30 | LockPersonality=yes 31 | SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap 32 | 33 | # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html 34 | CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD 35 | CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE 36 | CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT 37 | CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK 38 | CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM 39 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG 40 | CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE 41 | CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW 42 | CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG 43 | 44 | [Install] 45 | WantedBy=multi-user.target 46 | -------------------------------------------------------------------------------- /conf/seahub.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seafile hub 3 | After=network.target seafile.service 4 | 5 | [Service] 6 | Type=forking 7 | ExecStart=/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub.sh start 8 | ExecStop=/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub.sh stop 9 | User=__APP__ 10 | Group=__APP__ 11 | 12 | # Config related to run in docker provided file system 13 | RootDirectory=__INSTALL_DIR__/seafile_image 14 | BindPaths=__SYSTEMD_SEAFILE_BIND_MOUNT__ 15 | EnvironmentFile=__INSTALL_DIR__/seafile_env.conf 16 | 17 | # Sandboxing options to harden security 18 | # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html 19 | NoNewPrivileges=yes 20 | PrivateTmp=yes 21 | PrivateDevices=yes 22 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 23 | RestrictNamespaces=yes 24 | RestrictRealtime=yes 25 | DevicePolicy=closed 26 | ProtectSystem=full 27 | ProtectControlGroups=yes 28 | ProtectKernelModules=yes 29 | ProtectKernelTunables=yes 30 | LockPersonality=yes 31 | SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap 32 | 33 | # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html 34 | CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD 35 | CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE 36 | CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT 37 | CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK 38 | CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM 39 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG 40 | CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE 41 | CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW 42 | CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG 43 | 44 | [Install] 45 | WantedBy=multi-user.target 46 | -------------------------------------------------------------------------------- /conf/seafile.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seafile 3 | After=network.target 4 | After=mysql.service 5 | 6 | [Service] 7 | Type=forking 8 | ExecStart=/opt/seafile/seafile-server-__SEAFILE_VERSION__/seafile.sh start 9 | ExecStop=/opt/seafile/seafile-server-__SEAFILE_VERSION__/seafile.sh stop 10 | User=__APP__ 11 | Group=__APP__ 12 | RuntimeDirectory=__APP__/pids 13 | RuntimeDirectoryPreserve=yes 14 | 15 | # Config related to run in docker provided file system 16 | RootDirectory=__INSTALL_DIR__/seafile_image 17 | BindPaths=__SYSTEMD_SEAFILE_BIND_MOUNT__ 18 | EnvironmentFile=__INSTALL_DIR__/seafile_env.conf 19 | 20 | # Sandboxing options to harden security 21 | # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html 22 | NoNewPrivileges=yes 23 | PrivateTmp=yes 24 | PrivateDevices=yes 25 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 26 | RestrictNamespaces=yes 27 | RestrictRealtime=yes 28 | DevicePolicy=closed 29 | ProtectSystem=full 30 | ProtectControlGroups=yes 31 | ProtectKernelModules=yes 32 | ProtectKernelTunables=yes 33 | LockPersonality=yes 34 | SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap 35 | 36 | # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html 37 | CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD 38 | CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE 39 | CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT 40 | CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK 41 | CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM 42 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG 43 | CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE 44 | CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW 45 | CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG 46 | 47 | [Install] 48 | WantedBy=multi-user.target 49 | -------------------------------------------------------------------------------- /scripts/backup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ../settings/scripts/_common.sh 9 | 10 | if systemctl is-active "$app" --quiet || systemctl is-active seahub --quiet; then 11 | ynh_print_warn "It's hightly recommended to make your backup when the service is stopped. Please stop seafile service and seahub service with this command before to run the backup 'systemctl stop seafile.service seahub.service'" 12 | fi 13 | 14 | #================================================= 15 | # STANDARD BACKUP STEPS 16 | #================================================= 17 | 18 | # # Backup app files 19 | ynh_print_info "Backing up code..." 20 | ynh_backup "$install_dir" 21 | ynh_print_info "Backing up user data..." 22 | ynh_backup "$data_dir" --dest_path="data" 23 | 24 | ynh_print_info "Backing up configuration..." 25 | ynh_backup "/etc/nginx/conf.d/$domain.d/${app}.conf" 26 | 27 | ynh_backup /etc/systemd/system/"$app".service 28 | ynh_backup /etc/systemd/system/seahub.service 29 | ynh_backup /etc/systemd/system/"$app"-notification.service 30 | ynh_backup "/etc/systemd/system/$app-doc-server.service" 31 | ynh_backup "/etc/systemd/system/$app-doc-converter.service" 32 | if [ "$YNH_ARCH" != arm64 ]; then 33 | ynh_backup "/etc/systemd/system/$app-thumbnail.service" 34 | fi 35 | 36 | ynh_backup /etc/fail2ban/jail.d/"$app".conf 37 | ynh_backup /etc/fail2ban/filter.d/"$app".conf 38 | 39 | # Backup logs 40 | ynh_backup "/var/log/$app" 41 | 42 | # Backup mysql 43 | ynh_print_info "Backing up database" 44 | ynh_mysql_dump_db > "${YNH_CWD}"/seafiledb.dmp 45 | ynh_mysql_dump_db ccnetdb > "${YNH_CWD}"/ccnetdb.dmp 46 | ynh_mysql_dump_db seahubdb > "${YNH_CWD}"/seahubdb.dmp 47 | 48 | ynh_print_info "Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 5 | 6 |

7 | Logo of Seafile 8 | Seafile, packaged for YunoHost 9 |

10 | 11 | Open source cloud storage 12 | 13 | [![🌐 Official app website](https://img.shields.io/badge/Official_app_website-darkgreen?style=for-the-badge)](https://www.seafile.com) 14 | [![App Demo](https://img.shields.io/badge/App_Demo-blue?style=for-the-badge)](https://demo.seafile.com) 15 | [![Version: 13.0.12~ynh2](https://img.shields.io/badge/Version-13.0.12~ynh2-rgb(18,138,11)?style=for-the-badge)](https://ci-apps.yunohost.org/ci/apps/seafile/) 16 | 17 |
18 | 19 | 20 |
21 | 22 | 23 | ## Screenshots 24 | ![Screenshot of Seafile](./doc/screenshots/screenshot.png) 25 | 26 | ## 📦 Developer info 27 | 28 | [![Automatic tests level](https://apps.yunohost.org/badge/cilevel/seafile)](https://ci-apps.yunohost.org/ci/apps/seafile/) 29 | 30 | 🛠️ Upstream Seafile repository: 31 | 32 | Pull request are welcome and should target the [`testing` branch](https://github.com/YunoHost-Apps/seafile_ynh/tree/testing). 33 | 34 | The `testing` branch can be tested using: 35 | ``` 36 | # fresh install: 37 | sudo yunohost app install https://github.com/YunoHost-Apps/seafile_ynh/tree/testing 38 | 39 | # upgrade an existing install: 40 | sudo yunohost app upgrade seafile -u https://github.com/YunoHost-Apps/seafile_ynh/tree/testing 41 | ``` 42 | 43 | ### 📚 App packaging documentation 44 | 45 | Please see for more information. -------------------------------------------------------------------------------- /scripts/remove: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./_common.sh 9 | 10 | #================================================= 11 | # STANDARD REMOVE 12 | #================================================= 13 | 14 | ynh_script_progression "Stoping services..." 15 | 16 | # Stop all services 17 | ynh_systemctl --service="$app" --action=stop 18 | ynh_systemctl --service=seahub --action=stop 19 | ynh_systemctl --service="$app"-notification.service --action=stop 20 | ynh_systemctl --service="$app"-doc-server.service --action=stop 21 | ynh_systemctl --service="$app"-doc-converter.service --action=stop 22 | ynh_systemctl --service="$app"-thumbnail.service --action=stop 23 | 24 | # Force to kill all process in case of a process is not stoped cleanly 25 | pkill -f seafile-controller || true 26 | pkill -f seaf-server || true 27 | pkill -f ccnet-server || true 28 | pkill -f seahub || true 29 | 30 | # Remove databases 31 | ynh_script_progression "Removing databases..." 32 | ynh_''mysql_drop_db ccnetdb 33 | ynh_''mysql_drop_db seahubdb 34 | 35 | ynh_redis_remove_db "$redis_db" 36 | 37 | # Remove systemd service 38 | ynh_script_progression "Removing systemd units..." 39 | ynh_config_remove_systemd "$app" 40 | ynh_config_remove_systemd seahub 41 | ynh_config_remove_systemd "$app-notification" 42 | ynh_config_remove_systemd "$app-doc-server" 43 | ynh_config_remove_systemd "$app-doc-converter" 44 | if [ "$YNH_ARCH" != arm64 ]; then 45 | ynh_config_remove_systemd "$app-thumbnail" 46 | fi 47 | 48 | # Remove NGINX config 49 | ynh_script_progression "Removing NGINX configuration..." 50 | ynh_config_remove_nginx 51 | 52 | # Remove logrotate 53 | ynh_config_remove_logrotate 54 | 55 | # Remove the dedicated Fail2Ban config 56 | ynh_script_progression "Removing Fail2Ban configuration..." 57 | ynh_config_remove_fail2ban 58 | 59 | ynh_script_progression "Removing Seafile service..." 60 | yunohost service remove "$app" 61 | yunohost service remove seahub 62 | yunohost service remove "$app"-notification 63 | yunohost service remove "$app-doc-server" 64 | yunohost service remove "$app-doc-converter" 65 | if [ "$YNH_ARCH" != arm64 ]; then 66 | yunohost service remove "$app-thumbnail" 67 | fi 68 | 69 | ynh_script_progression "Removal of $app completed" 70 | 71 | sleep 1 72 | -------------------------------------------------------------------------------- /tests.toml: -------------------------------------------------------------------------------- 1 | #:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/tests.v1.schema.json 2 | 3 | test_format = 1.0 4 | 5 | [default] 6 | 7 | # ------------ 8 | # Tests to run 9 | # ------------ 10 | 11 | 12 | # ------------------------------- 13 | # Default args to use for install 14 | # ------------------------------- 15 | 16 | args.server_name = "Seafile" 17 | args.admin_password = "Sup3rS3cr3t" 18 | 19 | # ------------------------------- 20 | # Commits to test upgrade from 21 | # ------------------------------- 22 | 23 | test_upgrade_from.2036d090cb54a56a3922ea4bb2dc8d639107664c.name = "Version 8.x (Old_version_for_CI_5 branch)" 24 | test_upgrade_from.7a4d00a.name = "Version 9.x" 25 | test_upgrade_from.12a521d3b31cc838c3b93089d29fbe4c4bfb89e2.name = "Pre packaging v2 (Old_version_for_CI_6 branch)" 26 | test_upgrade_from.5a4717a.name = "Before helper 2.1" 27 | test_upgrade_from.f6160e7.name = "Seafile 11" 28 | test_upgrade_from.26e5265.name = "Seafile 12" 29 | 30 | # ------------------------------- 31 | # Curl tests to validate that the app works 32 | # ------------------------------- 33 | [default.curl_tests] 34 | login.path = "/" 35 | login.expect_title = "Log In - Private Seafile" 36 | 37 | home.path = "/" 38 | home.expect_title = "Private Seafile" 39 | home.logged_on_sso = true 40 | 41 | api.base_url = "https://__DOMAIN__" 42 | api.path = "/seafhttp/" 43 | api.expect_content = "404 page not found" 44 | api.expect_return_code = 404 45 | 46 | asset.path = "/media/avatars/default.png" 47 | 48 | notification.base_url = "https://__DOMAIN__" 49 | notification.path = "/notification/ping" 50 | notification.expect_content = "{\"ret\": \"pong\"}" 51 | 52 | sdoc.path = "/sdoc/api/v1/docs/" 53 | sdoc.expect_content = "{\"error_msg\":\"You don't have permission to access.\"}" 54 | sdoc.expect_return_code = 403 55 | 56 | sdocio.base_url = "https://__DOMAIN__" 57 | sdocio.path = "/socket.io/" 58 | sdocio.expect_content = "{\"code\":0,\"message\":\"Transport unknown\"}" 59 | sdocio.expect_return_code = 400 60 | 61 | thumbnail.path = "/thumbnail/" 62 | thumbnail.expect_content = "{\"error\": \"Page not found.\"}" 63 | thumbnail.expect_return_code = 404 64 | 65 | webdav.base_url = "https://__DOMAIN__" 66 | webdav.path = "/seafdav/Home/" 67 | webdav.logged_on_sso = false 68 | webdav.expect_title = "401 Access not authorized" 69 | webdav.expect_return_code = 401 70 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: When creating a bug report, please use the following template to provide all the relevant information and help debugging efficiently. 4 | 5 | --- 6 | 7 | **How to post a meaningful bug report** 8 | 1. *Read this whole template first.* 9 | 2. *Determine if you are on the right place:* 10 | - *If you were performing an action on the app from the webadmin or the CLI (install, update, backup, restore, change_url...), you are on the right place!* 11 | - *Otherwise, the issue may be due to the app itself. Refer to its documentation or repository for help.* 12 | - *When in doubt, post here and we will figure it out together.* 13 | 3. *Delete the italic comments as you write over them below, and remove this guide.* 14 | --- 15 | 16 | ### Describe the bug 17 | 18 | *A clear and concise description of what the bug is.* 19 | 20 | ### Context 21 | 22 | - Hardware: *VPS bought online / Old laptop or computer / Raspberry Pi at home / Internet Cube with VPN / Other ARM board / ...* 23 | - YunoHost version: x.x.x 24 | - I have access to my server: *Through SSH | through the webadmin | direct access via keyboard / screen | ...* 25 | - Are you in a special context or did you perform some particular tweaking on your YunoHost instance?: *no / yes* 26 | - If yes, please explain: 27 | - Using, or trying to install package version/branch: 28 | - If upgrading, current package version: *can be found in the admin, or with `yunohost app info $app_id`* 29 | 30 | ### Steps to reproduce 31 | 32 | - *If you performed a command from the CLI, the command itself is enough. For example:* 33 | ```sh 34 | sudo yunohost app install the_app 35 | ``` 36 | - *If you used the webadmin, please perform the equivalent command from the CLI first.* 37 | - *If the error occurs in your browser, explain what you did:* 38 | 1. *Go to '...'* 39 | 2. *Click on '...'* 40 | 3. *Scroll down to '...'* 41 | 4. *See error* 42 | 43 | ### Expected behavior 44 | 45 | *A clear and concise description of what you expected to happen. You can remove this section if the command above is enough to understand your intent.* 46 | 47 | ### Logs 48 | 49 | *When an operation fails, YunoHost provides a simple way to share the logs.* 50 | - *In the webadmin, the error message contains a link to the relevant log page. On that page, you will be able to 'Share with Yunopaste'. If you missed it, the logs of previous operations are also available under Tools > Logs.* 51 | - *In command line, the command to share the logs is displayed at the end of the operation and looks like `yunohost log display [log name] --share`. If you missed it, you can find the log ID of a previous operation using `yunohost log list`.* 52 | 53 | *After sharing the log, please copypaste directly the link provided by YunoHost (to help readability, no need to copypaste the entire content of the log here, just the link is enough...)* 54 | 55 | *If applicable and useful, add screenshots to help explain your problem.* 56 | -------------------------------------------------------------------------------- /scripts/change_url: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./_common.sh 9 | 10 | #================================================= 11 | 12 | ynh_script_progression "Updating NGINX web server configuration..." 13 | ynh_config_change_url_nginx 14 | 15 | #================================================= 16 | # SPECIFIC MODIFICATIONS 17 | #================================================= 18 | 19 | ynh_script_progression "Stoping services..." 20 | 21 | # Stop service before any change 22 | ynh_systemctl --service=seafile --action=stop 23 | ynh_systemctl --service=seahub --action=stop 24 | ynh_systemctl --service="$app"-notification.service --action=stop 25 | ynh_systemctl --service="$app"-doc-server.service --action=stop 26 | ynh_systemctl --service="$app"-doc-converter.service --action=stop 27 | if [ "$YNH_ARCH" != arm64 ]; then 28 | ynh_systemctl --service="$app"-thumbnail.service --action=stop 29 | fi 30 | sleep 2 31 | pkill -f seafile-controller || true 32 | pkill -f seaf-server || true 33 | pkill -f ccnet-server || true 34 | pkill -f seahub || true 35 | 36 | ynh_script_progression "Updating Seafile configuration..." 37 | 38 | # Update Seafile Config 39 | ynh_config_add --jinja --template=seahub_settings.py --destination="$install_dir"/conf/seahub_settings.py 40 | ynh_config_add --template=seafile.conf --destination="$install_dir"/conf/seafile.conf 41 | ynh_config_add --template=gunicorn.conf.py --destination="$install_dir"/conf/gunicorn.conf.py 42 | ynh_config_add --template=seafdav.conf --destination="$install_dir"/conf/seafdav.conf 43 | ynh_config_add --template=seafevents.conf --destination="$install_dir"/conf/seafevents.conf 44 | configure_env_files 45 | 46 | # Update permissions 47 | if [ "$old_domain" != "$domain" ]; then 48 | ynh_permission_url --permission=main --remove_url="$old_domain"/socket.io --add_url="$domain"/socket.io 49 | fi 50 | ynh_permission_url --permission=file_server --url="$domain"/seafhttp 51 | ynh_permission_url --permission=webdav --url="$domain"/seafdav 52 | ynh_permission_url --permission=notification --url="$domain"/notification 53 | 54 | # Clean url in config in DB 55 | clean_url_in_db_config 56 | 57 | # Avoid the current effect 58 | sleep 2 59 | 60 | # Reload services 61 | ynh_script_progression "Starting services..." 62 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 63 | sleep 2 64 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 65 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 66 | ynh_systemctl --service="$app"-doc-server.service --wait_until="server is serve on http://127.0.0.1" --log_path=systemd 67 | ynh_systemctl --service="$app"-doc-converter.service --log_path=systemd 68 | if [ "$YNH_ARCH" != arm64 ]; then 69 | ynh_systemctl --service="$app"-thumbnail.service --log_path=systemd 70 | fi 71 | 72 | ynh_script_progression "Change of URL completed for $app" --time= 73 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | location __PATH__ { 3 | proxy_pass http://127.0.0.1:__PORT_SEAHUB__; 4 | proxy_set_header Host $host; 5 | proxy_set_header X-Real-IP $remote_addr; 6 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 7 | proxy_set_header X-Forwarded-Host $server_name; 8 | proxy_set_header Ynh-User-Email $http_ynh_user_email; 9 | 10 | proxy_read_timeout 1200s; 11 | client_max_body_size 0; 12 | 13 | include conf.d/yunohost_panel.conf.inc; 14 | } 15 | 16 | location __PATH__/media/ { 17 | alias __SEAFILE_CODE__/seahub/media/; 18 | } 19 | 20 | location __PATH__/media/avatars/ { 21 | alias __DATA_DIR__/seahub-data/avatars/; 22 | } 23 | 24 | location /seafhttp/ { 25 | proxy_pass http://127.0.0.1:__PORT_FILESERVER__/; 26 | proxy_connect_timeout 36000s; 27 | proxy_read_timeout 36000s; 28 | proxy_send_timeout 36000s; 29 | 30 | client_max_body_size 0; 31 | proxy_request_buffering off; 32 | } 33 | 34 | location /notification/ping { 35 | proxy_pass http://127.0.0.1:__PORT_NOTIFICATIONSERVER__/ping; 36 | } 37 | 38 | location /notification { 39 | proxy_pass http://127.0.0.1:__PORT_NOTIFICATIONSERVER__/; 40 | proxy_http_version 1.1; 41 | proxy_set_header Upgrade $http_upgrade; 42 | proxy_set_header Connection "upgrade"; 43 | } 44 | 45 | location /seafdav { 46 | rewrite ^/seafdav$ /seafdav/ permanent; 47 | } 48 | 49 | location /seafdav/ { 50 | proxy_pass http://127.0.0.1:__PORT_WEBDAV__/seafdav/; 51 | proxy_set_header Host $host; 52 | proxy_set_header X-Real-IP $remote_addr; 53 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 54 | proxy_set_header X-Forwarded-Host $server_name; 55 | proxy_set_header X-Forwarded-Proto $scheme; 56 | 57 | proxy_read_timeout 1200s; 58 | client_max_body_size 0; 59 | proxy_request_buffering off; 60 | } 61 | 62 | location __PATH__/sdoc/ { 63 | proxy_pass http://127.0.0.1:__PORT_SEADOC__/; 64 | proxy_redirect off; 65 | proxy_set_header Host $host; 66 | proxy_set_header X-Real-IP $remote_addr; 67 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 68 | proxy_set_header X-Forwarded-Host $server_name; 69 | proxy_set_header X-Forwarded-Proto $scheme; 70 | 71 | client_max_body_size 100m; 72 | } 73 | 74 | location __PATH__/thumbnail/ { 75 | proxy_pass http://127.0.0.1:__PORT_THUMBNAIL__; 76 | proxy_redirect off; 77 | proxy_set_header Host $host; 78 | proxy_set_header X-Real-IP $remote_addr; 79 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 80 | proxy_set_header X-Forwarded-Host $server_name; 81 | proxy_set_header X-Forwarded-Proto $scheme; 82 | 83 | client_max_body_size 100m; 84 | } 85 | 86 | location /socket.io { 87 | proxy_pass http://127.0.0.1:__PORT_SEADOC__; 88 | proxy_http_version 1.1; 89 | proxy_set_header Upgrade $http_upgrade; 90 | proxy_set_header Connection 'upgrade'; 91 | proxy_redirect off; 92 | 93 | proxy_buffers 8 32k; 94 | proxy_buffer_size 64k; 95 | 96 | proxy_set_header X-Real-IP $remote_addr; 97 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 98 | proxy_set_header Host $host; 99 | proxy_set_header X-NginX-Proxy true; 100 | } 101 | -------------------------------------------------------------------------------- /scripts/restore: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ../settings/scripts/_common.sh 9 | 10 | ynh_script_progression "Loading settings..." 11 | 12 | #================================================= 13 | # STANDARD RESTORATION STEPS 14 | #================================================= 15 | 16 | # Restore all config and data 17 | ynh_script_progression "Restoring files..." 18 | ynh_restore_everything 19 | # Restore mysql dump 20 | ynh_script_progression "Restoring database..." 21 | ynh_''mysql_create_db ccnetdb "$db_user" "$db_pwd" 22 | ynh_''mysql_create_db seahubdb "$db_user" "$db_pwd" 23 | su -c "mysql -u ${app} -p$db_pwd $db_name < ${YNH_CWD}/seafiledb.dmp" 24 | su -c "mysql -u ${app} -p$db_pwd ccnetdb < ${YNH_CWD}/ccnetdb.dmp" 25 | su -c "mysql -u ${app} -p$db_pwd seahubdb < ${YNH_CWD}/seahubdb.dmp" 26 | 27 | redis_db=$(ynh_redis_get_free_db) 28 | ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db" 29 | ynh_config_add --jinja --template=seahub_settings.py --destination="$install_dir"/conf/seahub_settings.py 30 | 31 | #================================================= 32 | 33 | # Add logrotate 34 | ynh_script_progression "Configuring log rotation..." 35 | mkdir -p /var/log/"$app" 36 | ynh_config_add_logrotate /var/log/"$app" 37 | 38 | # Set all permissions 39 | ynh_script_progression "Protecting directory..." 40 | set_permission 41 | 42 | # Enable service and start seafile 43 | ynh_script_progression "Reconfiguring application..." 44 | systemctl daemon-reload 45 | systemctl enable "$app" --quiet 46 | systemctl enable seahub --quiet 47 | systemctl enable "$app"-notification --quiet 48 | systemctl enable "$app-doc-server" --quiet 49 | systemctl enable "$app-doc-converter" --quiet 50 | if [ "$YNH_ARCH" != arm64 ]; then 51 | systemctl enable "$app-thumbnail" --quiet 52 | fi 53 | 54 | # Add Seafile to YunoHost's monitored services 55 | ynh_script_progression "Register Seafile service..." 56 | yunohost service add "$app" --description 'Main service for seafile server.' 57 | yunohost service add seahub --description 'Seafile server web interface.' 58 | yunohost service add "$app"-notification --description 'Seafile client notification server.' 59 | yunohost service add "$app-doc-server" --description 'Seafile online collaborative document editor server.' 60 | yunohost service add "$app-doc-converter" --description 'Seafile online collaborative document editor converter.' 61 | if [ "$YNH_ARCH" != arm64 ]; then 62 | yunohost service add "$app-thumbnail" --description 'Server to create thumbnails for images, videos, PDFs and other file types.' 63 | fi 64 | 65 | ynh_script_progression "Reloading services..." 66 | 67 | # Reload NGINX 68 | systemctl reload nginx.service 69 | 70 | # Reload Fail2Ban 71 | ynh_systemctl --service=fail2ban --action=reload 72 | 73 | # Avoid the current effect 74 | sleep 5 75 | 76 | # Restart service 77 | ynh_script_progression "Starting Seafile services..." 78 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 79 | sleep 2 80 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 81 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 82 | ynh_systemctl --service="$app"-doc-server.service --wait_until="server is serve on http://127.0.0.1" --log_path=systemd 83 | ynh_systemctl --service="$app"-doc-converter.service --log_path=systemd 84 | if [ "$YNH_ARCH" != arm64 ]; then 85 | ynh_systemctl --service="$app"-thumbnail.service --log_path=systemd 86 | fi 87 | 88 | ynh_script_progression "Restoration completed for $app" 89 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | *.publishproj 131 | 132 | # Windows Azure Build Output 133 | csx 134 | *.build.csdef 135 | 136 | # Windows Store app package directory 137 | AppPackages/ 138 | 139 | # Others 140 | sql/ 141 | *.Cache 142 | ClientBin/ 143 | [Ss]tyle[Cc]op.* 144 | ~$* 145 | *~ 146 | *.dbmdl 147 | *.[Pp]ublish.xml 148 | *.pfx 149 | *.publishsettings 150 | 151 | # RIA/Silverlight projects 152 | Generated_Code/ 153 | 154 | # Backup & report files from converting an old project file to a newer 155 | # Visual Studio version. Backup files are not needed, because we have git ;-) 156 | _UpgradeReport_Files/ 157 | Backup*/ 158 | UpgradeLog*.XML 159 | UpgradeLog*.htm 160 | 161 | # SQL Server files 162 | App_Data/*.mdf 163 | App_Data/*.ldf 164 | 165 | ############# 166 | ## Windows detritus 167 | ############# 168 | 169 | # Windows image file caches 170 | Thumbs.db 171 | ehthumbs.db 172 | 173 | # Folder config file 174 | Desktop.ini 175 | 176 | # Recycle Bin used on file shares 177 | $RECYCLE.BIN/ 178 | 179 | # Mac crap 180 | .DS_Store 181 | 182 | 183 | ############# 184 | ## Python 185 | ############# 186 | 187 | *.py[cod] 188 | 189 | # Packages 190 | *.egg 191 | *.egg-info 192 | dist/ 193 | build/ 194 | eggs/ 195 | parts/ 196 | var/ 197 | sdist/ 198 | develop-eggs/ 199 | .installed.cfg 200 | 201 | # Installer logs 202 | pip-log.txt 203 | 204 | # Unit test / coverage reports 205 | .coverage 206 | .tox 207 | 208 | #Translations 209 | *.mo 210 | 211 | #Mr Developer 212 | .mr.developer.cfg 213 | 214 | .idea 215 | 216 | 217 | # From kateproject 218 | .kateproject 219 | .kateproject.d 220 | .directory 221 | *-swp 222 | 223 | auto_update_config.sh 224 | *.sw[op] 225 | -------------------------------------------------------------------------------- /auto_update/auto_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | readonly app_name=seafile 6 | 7 | source auto_update_config.sh 8 | 9 | get_from_manifest() { 10 | result=$(python3 <&1 | tee "${app_name}_build_temp.log" 90 | return "${PIPESTATUS[0]}" 91 | } 92 | 93 | app_prev_version="$(get_from_manifest ".version" | cut -d'~' -f1)" 94 | app_version="$app_prev_version" 95 | 96 | if check_app_version 97 | then 98 | set +eu 99 | upgrade_app 100 | res=$? 101 | set -eu 102 | if [ $res -eq 0 ]; then 103 | result="Success" 104 | else 105 | result="Failed" 106 | fi 107 | msg="Build: $app_name version $app_version" 108 | 109 | echo "$msg" | mail.mailutils --content-type="text/plain; charset=UTF-8" -A "${app_name}_build_temp.log" -s "Autoupgrade $app_name : $result" "$notify_email" 110 | fi 111 | -------------------------------------------------------------------------------- /manifest.toml: -------------------------------------------------------------------------------- 1 | packaging_format = 2 2 | 3 | id = "seafile" 4 | name = "Seafile" 5 | description.en = "Open source cloud storage" 6 | description.fr = "Stockage cloud open source" 7 | 8 | version = "13.0.12~ynh2" 9 | 10 | maintainers = ["Josué Tille"] 11 | 12 | [upstream] 13 | license = "AGPL-3.0,Apache-2.0,MIT,GPL-2.0" 14 | website = "https://www.seafile.com" 15 | demo = "https://demo.seafile.com" 16 | admindoc = "https://manual.seafile.com" 17 | code = "https://github.com/haiwen/seafile-server" 18 | cpe = "cpe:2.3:a:seafile:seafile" 19 | 20 | [integration] 21 | yunohost = ">= 11.2.30" 22 | helpers_version = "2.1" 23 | architectures = ["amd64", "arm64"] 24 | multi_instance = false 25 | 26 | ldap = true 27 | sso = true 28 | 29 | disk = "5G" 30 | ram.build = "0M" 31 | ram.runtime = "1G" 32 | 33 | [install] 34 | [install.domain] 35 | # this is a generic question - ask strings are automatically handled by YunoHost's core 36 | type = "domain" 37 | 38 | [install.path] 39 | # this is a generic question - ask strings are automatically handled by YunoHost's core 40 | type = "path" 41 | default = "/seafile" 42 | 43 | [install.server_name] 44 | ask.en = "Choose a name (3 - 15 letters or digits)" 45 | ask.fr = "Choisissez un nom (3 - 15 letters or digits)" 46 | type = "string" 47 | example = "Seafile" 48 | default = "Seafile" 49 | 50 | [install.admin] 51 | # this is a generic question - ask strings are automatically handled by YunoHost's core 52 | type = "user" 53 | 54 | [install.admin_password] 55 | ask.en = "Enter a password for the administrator" 56 | ask.fr = "Entrez un mot de passe pour l'administrateur" 57 | type = "password" 58 | 59 | [install.init_main_permission] 60 | help.en = "If it's not public, everybody which want to access to any page of seafile need to be authenticated on the SSO. On the public mode anybody can access to the authentication page. The shared link will be olso accessible by anybody who has this link." 61 | help.fr = "Si n'est pas publique, n'importe qui veux accéder à n'importe quelle page de seafile doit être authentifié dans le SSO. Dans le mode publique n'importe qui peut accéder à la page d'authentification de seafile. Les liens partagé seront aussi accessible par n'import qui qui à ce liens." 62 | type = "group" 63 | default = "visitors" 64 | 65 | [resources] 66 | [resources.system_user] 67 | allow_email = true 68 | 69 | [resources.install_dir] 70 | owner = "__APP__:rwx" 71 | group = "www-data:r-x" 72 | 73 | [resources.data_dir] 74 | dir = "/home/yunohost.app/__APP__" 75 | 76 | [resources.permissions] 77 | main.url = "/" 78 | main.additional_urls = ["__DOMAIN__/socket.io"] 79 | 80 | file_server.url = "__DOMAIN__/seafhttp" 81 | file_server.label = "File server" 82 | file_server.allowed = "visitors" 83 | file_server.auth_header = false 84 | file_server.show_tile = false 85 | file_server.protected = true 86 | 87 | notification.url = "__DOMAIN__/notification" 88 | notification.label = "Client-notification" 89 | notification.allowed = "visitors" 90 | notification.auth_header = false 91 | notification.show_tile = false 92 | notification.protected = true 93 | 94 | seadoc.url = "/sdoc" 95 | seadoc.label = "Seadoc" 96 | seadoc.allowed = "visitors" 97 | seadoc.auth_header = false 98 | seadoc.show_tile = false 99 | seadoc.protected = true 100 | 101 | webdav.url = "__DOMAIN__/seafdav" 102 | webdav.label = "Webdav" 103 | webdav.allowed = "visitors" 104 | webdav.auth_header = false 105 | webdav.show_tile = false 106 | webdav.protected = true 107 | 108 | media.url = "/media" 109 | media.label = "Media" 110 | media.allowed = "visitors" 111 | media.auth_header = true 112 | media.show_tile = false 113 | media.protected = true 114 | 115 | thumbnail.url = "/thumbnail" 116 | thumbnail.label = "Thumbnail" 117 | thumbnail.allowed = "visitors" 118 | thumbnail.auth_header = false 119 | thumbnail.show_tile = false 120 | thumbnail.protected = true 121 | 122 | [resources.ports] 123 | seahub.default = 8000 124 | fileserver.default = 8082 125 | notificationserver.default = 8083 126 | webdav.default = 8080 127 | seadoc.default = 8084 128 | thumbnail.default = 8085 129 | 130 | [resources.sources.main] 131 | format = "docker" 132 | extract = true 133 | prefetch = false 134 | 135 | amd64.url = "seafileltd/seafile-mc:13.0.12" 136 | amd64.sha256 = "312197aca67ec2066aefea4a0fa43d6f7cb65d45590c96ae38fe79aa44a5cdb9" 137 | 138 | arm64.url = "seafileltd/seafile-mc:13.0.12" 139 | arm64.sha256 = "312197aca67ec2066aefea4a0fa43d6f7cb65d45590c96ae38fe79aa44a5cdb9" 140 | 141 | [resources.sources.notification_server] 142 | format = "docker" 143 | extract = true 144 | prefetch = false 145 | 146 | amd64.url = "seafileltd/notification-server:13.0.10" 147 | amd64.sha256 = "a7159d04630bb4d0fcae56fb11294576ee1462fd98feb6fa27b2a2ee435b3945" 148 | 149 | arm64.url = "seafileltd/notification-server:13.0.10" 150 | arm64.sha256 = "a7159d04630bb4d0fcae56fb11294576ee1462fd98feb6fa27b2a2ee435b3945" 151 | 152 | [resources.sources.seadoc] 153 | format = "docker" 154 | extract = true 155 | prefetch = false 156 | 157 | amd64.url = "seafileltd/sdoc-server:2.0.8" 158 | amd64.sha256 = "50dab9bea6d3efb33d496e2d541d674ac4ca892b916f761ffe17beafb9014682" 159 | 160 | arm64.url = "seafileltd/sdoc-server:2.0.8" 161 | arm64.sha256 = "50dab9bea6d3efb33d496e2d541d674ac4ca892b916f761ffe17beafb9014682" 162 | 163 | [resources.sources.thumbnail_server] 164 | format = "docker" 165 | extract = true 166 | prefetch = false 167 | 168 | amd64.url = "seafileltd/thumbnail-server:13.0.12" 169 | amd64.sha256 = "04e049f308eec5f64b40e942f9553e5ae3de0a05fac2d9a86e1bd374beab0cae" 170 | 171 | [resources.apt] 172 | packages = ["mariadb-server", "redis-server"] 173 | 174 | [resources.database] 175 | type = "mysql" 176 | -------------------------------------------------------------------------------- /patches/main/import_ldap_user_when_authenticated_from_remoteUserBackend.patch: -------------------------------------------------------------------------------- 1 | diff --git a/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/auth/backends.py b/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/auth/backends.py 2 | index 885e291c1..00c44b268 100644 3 | --- a/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/auth/backends.py 4 | +++ b/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/auth/backends.py 5 | @@ -27,6 +27,9 @@ try: 6 | except ImportError: 7 | CUSTOM_GET_USER_ROLE = False 8 | 9 | +# BEGIN YNH PATCH 10 | +from seahub.base.accounts import CustomLDAPBackend 11 | +# END YNH PATCH 12 | 13 | # No longer maintained 14 | # Only used for old code of shibboleth authenticate 15 | @@ -97,6 +100,12 @@ class SeafileRemoteUserBackend(AuthBackend): 16 | auto_activate = getattr(settings, 17 | 'REMOTE_USER_ACTIVATE_USER_AFTER_CREATION', True) 18 | 19 | + # BEGIN YNH PATCH 20 | + import_from_ldap = getattr(settings, 'REMOTE_USER_IMPORT_FROM_LDAP', 21 | + True) 22 | + ldapBackend = CustomLDAPBackend() 23 | + # BEGIN YNH PATCH 24 | + 25 | # map user attribute in HTTP header and Seahub user attribute 26 | # REMOTE_USER_ATTRIBUTE_MAP = { 27 | # 'HTTP_DISPLAYNAME': 'name', 28 | @@ -143,6 +152,12 @@ class SeafileRemoteUserBackend(AuthBackend): 29 | 30 | # get user from ccnet 31 | user = self.get_user(username) 32 | + 33 | + # BEGIN YNH PATCH 34 | + if not user and self.import_from_ldap: 35 | + user = self.ldapBackend.authenticate(ldap_user=username, password=None, no_check_password=True) 36 | + # END YNH PATCH 37 | + 38 | if not user: 39 | # when user doesn't exist 40 | if not self.create_unknown_user: 41 | @@ -195,6 +210,11 @@ class SeafileRemoteUserBackend(AuthBackend): 42 | 43 | By default, returns the user unmodified. 44 | """ 45 | + # BEGIN YNH PATCH 46 | + if self.import_from_ldap: 47 | + self.ldapBackend.authenticate(ldap_user=user.username, password=None, no_check_password=True) 48 | + return 49 | + # END YNH PATCH 50 | 51 | user_info = self.parse_user_info(request, user) 52 | 53 | diff --git a/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/base/accounts.py b/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/base/accounts.py 54 | index cd218032b..a856bd21f 100644 55 | --- a/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/base/accounts.py 56 | +++ b/opt/seafile/seafile-server-__SEAFILE_VERSION__/seahub/seahub/base/accounts.py 57 | @@ -913,7 +913,10 @@ class CustomLDAPBackend(object): 58 | 59 | def search_user(self, server_url, admin_dn, admin_password, enable_sasl, sasl_mechanism, 60 | sasl_authc_id_attr, base_dn, login_attr_conf, login_attr, password, serch_filter, 61 | - contact_email_attr, role_attr, follow_referrals): 62 | + # BEGIN YNH PATCH 63 | + contact_email_attr, role_attr, follow_referrals, 64 | + no_check_password=False): 65 | + # END YNH PATCH 66 | try: 67 | admin_bind = self.ldap_bind(server_url, admin_dn, admin_dn, 68 | admin_password, enable_sasl, 69 | @@ -951,17 +954,22 @@ class CustomLDAPBackend(object): 70 | except Exception as e: 71 | raise Exception('parse ldap result failed: %s' % e) 72 | 73 | - try: 74 | - user_bind = self.ldap_bind(server_url, dn, authc_id, 75 | - password, enable_sasl, 76 | - sasl_mechanism, follow_referrals) 77 | - except Exception as e: 78 | - raise Exception(e) 79 | + # BEGIN YNH PATCH 80 | + if not no_check_password: 81 | + try: 82 | + user_bind = self.ldap_bind(server_url, dn, authc_id, 83 | + password, enable_sasl, 84 | + sasl_mechanism, follow_referrals) 85 | + except Exception as e: 86 | + raise Exception(e) 87 | 88 | - user_bind.unbind_s() 89 | + user_bind.unbind_s() 90 | + # END YNH PATCH 91 | return nickname, contact_email, user_role 92 | 93 | - def authenticate(self, ldap_user=None, password=None): 94 | + # BEGIN YNH PATCH 95 | + def authenticate(self, ldap_user=None, password=None, no_check_password=False): 96 | + # END YNH PATCH 97 | if not ENABLE_LDAP: 98 | return 99 | 100 | @@ -976,7 +984,9 @@ class CustomLDAPBackend(object): 101 | nickname, contact_email, user_role = self.search_user( 102 | LDAP_SERVER_URL, LDAP_ADMIN_DN, LDAP_ADMIN_PASSWORD, ENABLE_SASL, SASL_MECHANISM, 103 | SASL_AUTHC_ID_ATTR, LDAP_BASE_DN, LDAP_LOGIN_ATTR, login_attr, password, LDAP_FILTER, 104 | - LDAP_CONTACT_EMAIL_ATTR, LDAP_USER_ROLE_ATTR, LDAP_FOLLOW_REFERRALS) 105 | + # BEGIN YNH PATCH 106 | + LDAP_CONTACT_EMAIL_ATTR, LDAP_USER_ROLE_ATTR, LDAP_FOLLOW_REFERRALS, no_check_password) 107 | + # END YNH PATCH 108 | ldap_provider = LDAP_PROVIDER 109 | except Exception as e: 110 | if ENABLE_MULTI_LDAP: 111 | @@ -991,7 +1001,9 @@ class CustomLDAPBackend(object): 112 | MULTI_LDAP_1_SERVER_URL, MULTI_LDAP_1_ADMIN_DN, MULTI_LDAP_1_ADMIN_PASSWORD, 113 | MULTI_LDAP_1_ENABLE_SASL, MULTI_LDAP_1_SASL_MECHANISM, MULTI_LDAP_1_SASL_AUTHC_ID_ATTR, 114 | MULTI_LDAP_1_BASE_DN, MULTI_LDAP_1_LOGIN_ATTR, login_attr, password, MULTI_LDAP_1_FILTER, 115 | - MULTI_LDAP_1_CONTACT_EMAIL_ATTR, MULTI_LDAP_1_USER_ROLE_ATTR, MULTI_LDAP_1_FOLLOW_REFERRALS) 116 | + # BEGIN YNH PATCH 117 | + MULTI_LDAP_1_CONTACT_EMAIL_ATTR, MULTI_LDAP_1_USER_ROLE_ATTR, MULTI_LDAP_1_FOLLOW_REFERRALS, no_check_password) 118 | + # END YNH PATCH 119 | ldap_provider = MULTI_LDAP_1_PROVIDER 120 | except Exception as e: 121 | logger.error(e) 122 | -------------------------------------------------------------------------------- /scripts/install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./_common.sh 9 | source ./ynh_setup_source 10 | 11 | ensure_vars_set 12 | 13 | #================================================= 14 | 15 | ynh_script_progression "Creating base directory..." 16 | 17 | if [ -n "$(ls -A "$data_dir")" ]; then 18 | old_data_dir_path="${data_dir}_$(date '+%Y%m%d.%H%M%S')" 19 | ynh_print_warn "Data directory was not empty. Data was moved to $old_data_dir_path" 20 | mkdir -p "$old_data_dir_path" 21 | mv -t "$old_data_dir_path" "$data_dir"/* 22 | fi 23 | 24 | mkdir -p /var/log/"$app" 25 | mkdir -p "$data_dir"/{seafile-data,seahub-data,notification-data} 26 | mkdir -p "$install_dir"/{conf,ccnet,seadoc-conf} 27 | 28 | # Download new version from sources 29 | ynh_script_progression "Installing sources files..." 30 | install_source 31 | 32 | # init databases 33 | ynh_script_progression "Configuring MySQL database..." 34 | db_user=seafile 35 | ynh_''mysql_create_db ccnetdb "$db_user" "$db_pwd" 36 | ynh_''mysql_create_db seahubdb "$db_user" "$db_pwd" 37 | 38 | ynh_script_progression "Configuring redis database..." 39 | 40 | redis_db=$(ynh_redis_get_free_db) 41 | ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db" 42 | 43 | ynh_script_progression "Configuring application..." 44 | 45 | configure_env_files 46 | 47 | # Run install script 48 | set_permission 49 | ynh_replace_regex --match='seafile_config.seafile_dir = seafile_config.validate_seafile_dir(seafile_dir)' \ 50 | --replace='seafile_config.seafile_dir = seafile_dir' \ 51 | --file="$seafile_code/setup-seafile-mysql.py" 52 | ynh_replace_regex --match="Utils.error('Ccnet config dir \\\"%s\\\" already exists.' % ccnet_config.ccnet_dir)" \ 53 | --replace='patched = 1' \ 54 | --file="$seafile_code/setup-seafile-mysql.py" 55 | ynh_replace --match='db_config.root_conn.close()' \ 56 | --replace='patched = 1' \ 57 | --file="$seafile_code/setup-seafile-mysql.py" 58 | run_seafile_cmd bash "/opt/seafile/seafile-server-$seafile_version/setup-seafile-mysql.sh" auto \ 59 | --server-name "$server_name" \ 60 | --server-ip "$domain" \ 61 | --fileserver-port "$port_fileserver" \ 62 | --use-existing-db 1 \ 63 | --mysql-host 127.0.0.1 \ 64 | --mysql-port 3306 \ 65 | --mysql-user "$db_user" \ 66 | --mysql-user-passwd "$db_pwd" \ 67 | -s "$db_name" \ 68 | -c ccnetdb \ 69 | -b seahubdb 70 | 71 | # Retrive values from auto generated config file 72 | seahub_secret_key=$(grep -P 'SECRET_KEY\s*=\s*".+"' "$install_dir"/conf/seahub_settings.py | cut -d'"' -f2) 73 | ynh_app_setting_set --key=seahub_secret_key --value="$seahub_secret_key" 74 | 75 | # Update Seafile config files 76 | if [ "$(lsb_release -c -s)" == bullseye ]; then 77 | # Fix header for retro compability on YunoHost 11 78 | ynh_replace --match="'HTTP_YNH_USER_EMAIL'" --replace="'HTTP_EMAIL'" --file="../conf/seahub_settings.py" 79 | fi 80 | ynh_config_add --jinja --template=seahub_settings.py --destination="$install_dir"/conf/seahub_settings.py 81 | ynh_config_add --template=seafile.conf --destination="$install_dir"/conf/seafile.conf 82 | ynh_config_add --template=gunicorn.conf.py --destination="$install_dir"/conf/gunicorn.conf.py 83 | ynh_config_add --template=seafdav.conf --destination="$install_dir"/conf/seafdav.conf 84 | ynh_config_add --template=seafevents.conf --destination="$install_dir"/conf/seafevents.conf 85 | 86 | # Configure admin info 87 | # It will be used the first start 88 | admin_email=$(ynh_user_get_info --username="$admin" --key='mail') 89 | cp ../conf/create_admin.json "$install_dir"/conf/admin.txt 90 | ynh_replace --match=__ADMIN__ --replace="$admin_email" --file="$install_dir"/conf/admin.txt 91 | ynh_replace_regex --match=__PASSWORD__ --replace="$admin_password" --file="$install_dir"/conf/admin.txt 92 | 93 | # Fix local warning 94 | ynh_replace --match=en_US.UTF-8 --replace="${LANG:-'en_US.UTF-8'}" --file="$seafile_code/seahub.sh" 95 | 96 | # Add Seafile Server to startup 97 | ynh_script_progression "Configuring $app's systemd service..." 98 | configure_systemd_services 99 | 100 | # register YunoHost service 101 | yunohost service add "$app" --description 'Main service for seafile server.' 102 | yunohost service add seahub --description 'Seafile server web interface.' 103 | yunohost service add "$app"-notification --description 'Seafile client notification server.' 104 | yunohost service add "$app-doc-server" --description 'Seafile online collaborative document editor server.' 105 | yunohost service add "$app-doc-converter" --description 'Seafile online collaborative document editor converter.' 106 | if [ "$YNH_ARCH" != arm64 ]; then 107 | yunohost service add "$app-thumbnail" --description 'Server to create thumbnails for images, videos, PDFs and other file types.' 108 | fi 109 | 110 | # Config nginx 111 | ynh_script_progression "Configuring NGINX..." 112 | ynh_config_add_nginx 113 | 114 | # Add logrotate 115 | ynh_script_progression "Configuring log rotation..." 116 | ynh_config_add_logrotate /var/log/"$app" 117 | 118 | # Add fail2ban 119 | ynh_script_progression "Configuring Fail2Ban..." 120 | ynh_config_add_fail2ban --logpath="$install_dir"/logs/seahub.log 121 | 122 | #================================================= 123 | 124 | # Set all permissions 125 | ynh_script_progression "Protecting directory..." 126 | set_permission 127 | 128 | # Start service 129 | sleep 3 130 | 131 | ynh_script_progression "Starting seafile services..." 132 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 133 | sleep 2 134 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 135 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 136 | ynh_systemctl --service="$app"-doc-server.service --wait_until="server is serve on http://127.0.0.1" --log_path=systemd 137 | ynh_systemctl --service="$app"-doc-converter.service --log_path=systemd 138 | if [ "$YNH_ARCH" != arm64 ]; then 139 | ynh_systemctl --service="$app"-thumbnail.service --log_path=systemd 140 | fi 141 | 142 | ynh_script_progression "Installation of $app completed" 143 | -------------------------------------------------------------------------------- /scripts/_common.sh: -------------------------------------------------------------------------------- 1 | source /usr/share/yunohost/helpers 2 | 3 | #================================================= 4 | # SET ALL CONSTANTS 5 | #================================================= 6 | 7 | readonly seafile_version=$(ynh_app_upstream_version) 8 | 9 | readonly seafile_image="$install_dir/seafile_image" 10 | readonly notification_image="$install_dir/notification_image" 11 | readonly seadoc_image="$install_dir/seadoc_image" 12 | readonly thumbnail_server_image="$install_dir/thumbnail-server_image" 13 | readonly seafile_code="$seafile_image/opt/seafile/seafile-server-$seafile_version" 14 | 15 | readonly time_zone="$(timedatectl show --value --property=Timezone)" 16 | readonly python_version="$(python3 -V | cut -d' ' -f2 | cut -d. -f1-2)" 17 | readonly systemd_base_bind_mount="/proc /dev /usr/share/zoneinfo " 18 | systemd_seafile_bind_mount="$systemd_base_bind_mount" 19 | systemd_seafile_bind_mount+="$data_dir/seafile-data:/opt/seafile/seafile-data " 20 | systemd_seafile_bind_mount+="$data_dir/seahub-data:/opt/seafile/seahub-data " 21 | systemd_seafile_bind_mount+="/run/$app/pids:/opt/seafile/pids " 22 | systemd_seafile_bind_mount+="/var/log/$app:/opt/seafile/logs " 23 | systemd_seafile_bind_mount+="$install_dir/conf:/opt/seafile/conf " 24 | systemd_seafile_bind_mount+="$install_dir/ccnet:/opt/seafile/ccnet" 25 | 26 | systemd_notification_server_bind_mount="$systemd_base_bind_mount" 27 | systemd_notification_server_bind_mount+="$data_dir/notification-data:/opt/notification-data" 28 | 29 | systemd_seadoc_bind_mount="$systemd_base_bind_mount" 30 | systemd_seadoc_bind_mount+="$install_dir/seadoc-conf:/opt/sdoc-server/conf " 31 | systemd_seadoc_bind_mount+="/var/log/$app:/opt/sdoc-server/logs" 32 | 33 | systemd_thumbnail_bind_mount="$systemd_base_bind_mount" 34 | systemd_thumbnail_bind_mount+="$data_dir/seafile-data:/opt/seafile/seafile-data " 35 | systemd_thumbnail_bind_mount+="$data_dir/seahub-data:/opt/seafile/seahub-data " 36 | systemd_thumbnail_bind_mount+="/var/log/$app:/opt/seafile/logs " 37 | systemd_thumbnail_bind_mount+="$install_dir/conf:/opt/seafile/conf" 38 | 39 | # Create special path with / at the end 40 | if [[ "$path" == '/' ]] 41 | then 42 | readonly path2="$path" 43 | else 44 | readonly path2="$path/" 45 | fi 46 | 47 | if [ "${LANG:0:2}" == C. ] || [ "${LANG}" == C ]; then 48 | readonly language=en 49 | else 50 | readonly language="${LANG:0:2}" 51 | fi 52 | 53 | if [ "$YNH_ARCH" == arm64 ]; then 54 | port_thumbnail="$port_seahub" 55 | fi 56 | 57 | #================================================= 58 | # DEFINE ALL COMMON FONCTIONS 59 | #================================================= 60 | 61 | run_seafile_cmd() { 62 | ynh_hide_warnings "$install_dir/scripts/exec_in_seafile_image.sh" "$@" 63 | } 64 | 65 | update_pwd_group_shadow_in_docker() { 66 | # We remove all entries to just keep root + seafile users in the docker because we need to avoid any collision with other user ID which already in the 67 | echo 'root:x:0:0:root:/root:/bin/bash' > "$1/etc/passwd" 68 | grep "^$app:x" /etc/passwd | sed "s|$install_dir|/opt/seafile|" >> "$1/etc/passwd" 69 | 70 | echo 'root:x:0:' > "$1/etc/group" 71 | grep "^$app:x" /etc/group >> "$1/etc/group" 72 | 73 | grep "^$app:" /etc/shadow >> "$1/etc/shadow" 74 | } 75 | 76 | install_source() { 77 | # set correct seafile version in patch 78 | ynh_replace --match="__SEAFILE_VERSION__" --replace="$seafile_version" --file="$YNH_APP_BASEDIR"/patches/main/import_ldap_user_when_authenticated_from_remoteUserBackend.patch 79 | ynh_setup_source_custom --dest_dir="$seafile_image" --full_replace 80 | update_pwd_group_shadow_in_docker "$seafile_image" 81 | mkdir -p "$seafile_image/opt/seafile/"{seafile-data,seahub-data,conf,ccnet,logs,pids} 82 | 83 | ynh_setup_source_custom --dest_dir="$notification_image" --full_replace --source_id=notification_server 84 | update_pwd_group_shadow_in_docker "$notification_image" 85 | 86 | ynh_setup_source_custom --dest_dir="$seadoc_image" --full_replace --source_id=seadoc 87 | update_pwd_group_shadow_in_docker "$seadoc_image" 88 | mkdir -p "$seadoc_image/opt/sdoc-server/"{logs,conf} 89 | 90 | if [ "$YNH_ARCH" != arm64 ]; then 91 | ynh_setup_source_custom --dest_dir="$thumbnail_server_image" --full_replace --source_id=thumbnail_server 92 | update_pwd_group_shadow_in_docker "$thumbnail_server_image" 93 | mkdir -p "$thumbnail_server_image/opt/seafile/"{seafile-data,seahub-data,conf,logs} 94 | 95 | # workaround until https://github.com/haiwen/seafile-thumbnail-server/pull/11 is merged and released 96 | ynh_replace --match='config = uvicorn.Config(app, port=8088)' \ 97 | --replace="config = uvicorn.Config(app, port=$port_thumbnail)" \ 98 | --file="$thumbnail_server_image/opt/seafile/thumbnail-server/main.py" 99 | fi 100 | 101 | # Install exec scripts 102 | mkdir -p "$install_dir/scripts" 103 | for s in \ 104 | exec_in_seafile_image.sh \ 105 | exec_in_seadoc_image.sh \ 106 | exec_in_seafile_notification_image.sh \ 107 | exec_in_thumbnail_image.sh; do 108 | ynh_config_add --jinja --template="../sources/$s" --destination="$install_dir/scripts/$s" 109 | chmod 700 "$install_dir/scripts/$s" 110 | local r_user='root' 111 | chown "$r_user:$r_user" "$install_dir/scripts/$s" 112 | done 113 | } 114 | 115 | configure_env_files() { 116 | ynh_config_add --jinja --template=seafile_env.j2 --destination="$install_dir"/seafile_env.conf 117 | ynh_config_add --jinja --template=seafile-notification_env.j2 --destination="$install_dir"/notification_server_env.conf 118 | ynh_config_add --jinja --template=seafile-doc_env.j2 --destination="$install_dir/seadoc_env.conf" 119 | ynh_config_add --jinja --template=seafile-thumbnail_env.j2 --destination="$install_dir/thumbnail_env.conf" 120 | } 121 | 122 | configure_systemd_services() { 123 | # Add Seafile Server to startup 124 | ynh_config_add_systemd --service="$app" --template=seafile.service 125 | ynh_config_add_systemd --service=seahub --template=seahub.service 126 | ynh_config_add_systemd --service="$app-notification" --template=seafile-notification.service 127 | ynh_config_add_systemd --service="$app-doc-server" --template=seafile-doc-server.service 128 | ynh_config_add_systemd --service="$app-doc-converter" --template=seafile-doc-converter.service 129 | if [ "$YNH_ARCH" != arm64 ]; then 130 | ynh_config_add_systemd --service="$app-thumbnail" --template=seafile-thumbnail.service 131 | fi 132 | } 133 | 134 | set_permission() { 135 | chown "$app:$app" "$install_dir" 136 | chmod u=rwx,g=rx,o= "$install_dir" 137 | chown -R "$app:$app" "$install_dir"/{conf,ccnet} 138 | chmod -R u+rwX,g+rX-w,o= "$install_dir"/{conf,ccnet} 139 | chown -R "$app:$app" "$seafile_image/opt/seafile" 140 | chmod -R u+rwX,g-w,o= "$seafile_image/opt/seafile" 141 | chown -R "$app:$app" "$seadoc_image/opt/sdoc-server" 142 | chmod -R u+rwX,g-w,o= "$seadoc_image/opt/sdoc-server" 143 | chown -R "$app:$app" /var/log/"$app" 144 | chmod -R u=rwX,g=rX,o= /var/log/"$app" 145 | 146 | # Allow to www-data to each dir between /opt/yunohost/seafile and /opt/yunohost/seafile/seafile_image/opt/seafile/seahub/media 147 | local dir_path='' 148 | while read -r -d/ dir_name; do 149 | dir_path+="$dir_name/" 150 | if [[ "$dir_path" == "$install_dir"* ]] && [ -e "$dir_path" ]; then 151 | setfacl -m user:www-data:rX "$dir_path" 152 | fi 153 | done <<< "$seafile_code/seahub/media" 154 | test -e "$install_dir/seafile_image/opt/seafile/seahub-data" && setfacl -m user:www-data:rX "$install_dir/seafile_image/opt/seafile/seahub-data" 155 | test -e "$seafile_code/seahub/media" && setfacl -R -m user:www-data:rX "$seafile_code/seahub/media" 156 | 157 | setfacl -m user:www-data:rX "$data_dir" 158 | setfacl -R -m user:www-data:rX "$data_dir"/seahub-data 159 | 160 | chmod u=rwx,g=rx,o= "$data_dir" 161 | find "$data_dir" \( \! -perm -o= \ 162 | -o \! -user "$app" \ 163 | -o \! -group "$app" \) \ 164 | -exec chown "$app:$app" {} \; \ 165 | -exec chmod o= {} \; 166 | } 167 | 168 | clean_url_in_db_config() { 169 | sql_request='DELETE FROM `constance_config` WHERE `constance_key`= "SERVICE_URL"' 170 | ynh_mysql_db_shell <<< "$sql_request" --database=seahubdb 171 | sql_request='DELETE FROM `constance_config` WHERE `constance_key`= "FILE_SERVER_ROOT"' 172 | ynh_mysql_db_shell <<< "$sql_request" --database=seahubdb 173 | } 174 | 175 | ensure_vars_set() { 176 | ynh_app_setting_set_default --key=jwt_private --value=$(ynh_string_random -l 32) 177 | ynh_app_setting_set_default --key=protect_against_basic_auth_spoofing --value=false 178 | } 179 | -------------------------------------------------------------------------------- /scripts/ynh_setup_source: -------------------------------------------------------------------------------- 1 | # Download, check integrity, uncompress and patch upstream sources 2 | # 3 | # NOTE this is a full copy of upstream ynh_setup_source but with some specific patch releated to seafile docker archive 4 | ynh_setup_source_custom() { 5 | # ============ Argument parsing ============= 6 | local -A args_array=([d]=dest_dir= [s]=source_id= [k]=keep= [r]=full_replace) 7 | local dest_dir 8 | local source_id 9 | local keep 10 | local full_replace 11 | ynh_handle_getopts_args "$@" 12 | keep="${keep:-}" 13 | full_replace="${full_replace:-0}" 14 | source_id="${source_id:-main}" 15 | # =========================================== 16 | 17 | local sources_json=$(ynh_read_manifest "resources.sources[\"$source_id\"]") 18 | if jq -re ".url" <<< "$sources_json" 19 | then 20 | local arch_prefix="" 21 | else 22 | local arch_prefix=".$YNH_ARCH" 23 | fi 24 | 25 | local src_url="$(jq -r "$arch_prefix.url" <<< "$sources_json" | sed 's/^null$//')" 26 | local src_sum="$(jq -r "$arch_prefix.sha256" <<< "$sources_json" | sed 's/^null$//')" 27 | local src_format="$(jq -r ".format" <<< "$sources_json" | sed 's/^null$//')" 28 | local src_in_subdir="$(jq -r ".in_subdir" <<< "$sources_json" | sed 's/^null$//')" 29 | src_in_subdir=${src_in_subdir:-true} 30 | local src_extract="$(jq -r ".extract" <<< "$sources_json" | sed 's/^null$//')" 31 | local src_platform="$(jq -r ".platform" <<< "$sources_json" | sed 's/^null$//')" 32 | local src_rename="$(jq -r ".rename" <<< "$sources_json" | sed 's/^null$//')" 33 | 34 | [[ -n "$src_url" ]] || ynh_die "No URL defined for source $source_id$arch_prefix ?" 35 | [[ -n "$src_sum" ]] || ynh_die "No sha256 sum defined for source $source_id$arch_prefix ?" 36 | 37 | if [[ -z "$src_format" ]] 38 | then 39 | if [[ "$src_url" =~ ^.*\.zip$ ]] || [[ "$src_url" =~ ^.*/zipball/.*$ ]] 40 | then 41 | src_format="zip" 42 | elif [[ "$src_url" =~ ^.*\.tar\.gz$ ]] || [[ "$src_url" =~ ^.*\.tgz$ ]] || [[ "$src_url" =~ ^.*/tar\.gz/.*$ ]] || [[ "$src_url" =~ ^.*/tarball/.*$ ]] 43 | then 44 | src_format="tar.gz" 45 | elif [[ "$src_url" =~ ^.*\.tar\.xz$ ]] 46 | then 47 | src_format="tar.xz" 48 | elif [[ "$src_url" =~ ^.*\.tar\.bz2$ ]] 49 | then 50 | src_format="tar.bz2" 51 | elif [[ "$src_url" =~ ^.*\.tar$ ]] 52 | then 53 | src_format="tar" 54 | elif [[ -z "$src_extract" ]] 55 | then 56 | src_extract="false" 57 | fi 58 | fi 59 | 60 | src_format=${src_format:-tar.gz} 61 | src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]') 62 | src_extract=${src_extract:-true} 63 | 64 | if [[ "$src_extract" != "true" ]] && [[ "$src_extract" != "false" ]] 65 | then 66 | ynh_die "For source $source_id, expected either 'true' or 'false' for the extract parameter" 67 | fi 68 | 69 | # Gotta use this trick with 'dirname' because source_id may contain slashes x_x 70 | mkdir -p $(dirname /var/cache/yunohost/download/${YNH_APP_ID}/${source_id}) 71 | src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${source_id}" 72 | 73 | if [ "$src_format" = "docker" ]; then 74 | src_platform="${src_platform:-"linux/$YNH_ARCH"}" 75 | # BEGIN APP CUSTOMIZATION 76 | if [ "$YNH_ARCH" == arm64 ]; then 77 | src_platform="linux/$YNH_ARCH/v8" 78 | fi 79 | # END APP CUSTOMIZATION 80 | else 81 | [ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?" 82 | 83 | # If the file was prefetched but somehow doesn't match the sum, rm and redownload it 84 | if [ -e "$src_filename" ] && ! echo "${src_sum} ${src_filename}" | sha256sum --check --status 85 | then 86 | rm -f "$src_filename" 87 | fi 88 | 89 | # Only redownload the file if it wasnt prefetched 90 | if [ ! -e "$src_filename" ] 91 | then 92 | # NB. we have to declare the var as local first, 93 | # otherwise 'local foo=$(false) || echo 'pwet'" does'nt work 94 | # because local always return 0 ... 95 | local out 96 | # Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget) 97 | out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1) \ 98 | || ynh_die "$out" 99 | fi 100 | 101 | # Check the control sum 102 | if ! echo "${src_sum} ${src_filename}" | sha256sum --check --status 103 | then 104 | local actual_sum="$(sha256sum ${src_filename} | cut --delimiter=' ' --fields=1)" 105 | local actual_size="$(du -hs ${src_filename} | cut --fields=1)" 106 | rm -f ${src_filename} 107 | ynh_die "Corrupt source for ${src_url}: Expected sha256sum to be ${src_sum} but got ${actual_sum} (size: ${actual_size})." 108 | fi 109 | fi 110 | 111 | # Keep files to be backup/restored at the end of the helper 112 | # Assuming $dest_dir already exists 113 | rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/ 114 | if [ -n "$keep" ] && [ -e "$dest_dir" ]; then 115 | local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID} 116 | mkdir -p $keep_dir 117 | local stuff_to_keep 118 | for stuff_to_keep in $keep; do 119 | if [ -e "$dest_dir/$stuff_to_keep" ]; then 120 | mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")" 121 | cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep" 122 | fi 123 | done 124 | fi 125 | 126 | if [ "$full_replace" -eq 1 ]; then 127 | ynh_safe_rm "$dest_dir" 128 | fi 129 | 130 | # Extract source into the app dir 131 | mkdir --parents "$dest_dir" 132 | 133 | if [[ "$src_extract" == "false" ]]; then 134 | if [[ -z "$src_rename" ]] 135 | then 136 | mv $src_filename $dest_dir 137 | else 138 | mv $src_filename $dest_dir/$src_rename 139 | fi 140 | elif [[ "$src_format" == "docker" ]]; then 141 | "$YNH_HELPERS_DIR/vendor/docker-image-extract/docker-image-extract" -p $src_platform -o $dest_dir $src_url 2>&1 142 | elif [[ "$src_format" == "zip" ]]; then 143 | # Zip format 144 | # Using of a temp directory, because unzip doesn't manage --strip-components 145 | if $src_in_subdir; then 146 | local tmp_dir=$(mktemp --directory) 147 | unzip -quo $src_filename -d "$tmp_dir" 148 | cp --archive $tmp_dir/*/. "$dest_dir" 149 | ynh_safe_rm "$tmp_dir" 150 | else 151 | unzip -quo $src_filename -d "$dest_dir" 152 | fi 153 | ynh_safe_rm "$src_filename" 154 | else 155 | local strip="" 156 | if [ "$src_in_subdir" != "false" ]; then 157 | if [ "$src_in_subdir" == "true" ]; then 158 | local sub_dirs=1 159 | else 160 | local sub_dirs="$src_in_subdir" 161 | fi 162 | strip="--strip-components $sub_dirs" 163 | fi 164 | if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz|tar$ ]]; then 165 | tar --extract --file=$src_filename --directory="$dest_dir" $strip 166 | else 167 | ynh_die "Archive format unrecognized." 168 | fi 169 | ynh_safe_rm "$src_filename" 170 | fi 171 | 172 | # Apply patches 173 | if [ -d "$YNH_APP_BASEDIR/patches/" ]; then 174 | local patches_folder=$(realpath "$YNH_APP_BASEDIR/patches/$source_id") 175 | # BEGIN APP CUSTOMIZATION 176 | if [ -d "$patches_folder" ]; then 177 | # END APP CUSTOMIZATION 178 | pushd "$dest_dir" 179 | for patchfile in "$patches_folder/"*.patch; do 180 | echo "Applying $patchfile" 181 | if ! patch --strip=1 < "$patchfile"; then 182 | if ynh_in_ci_tests; then 183 | ynh_die "Patch $patchfile failed to apply!" 184 | else 185 | ynh_print_warn "Warn your packagers /!\\ Patch $patchfile failed to apply" 186 | fi 187 | fi 188 | done 189 | popd 190 | # BEGIN APP CUSTOMIZATION 191 | fi 192 | # END APP CUSTOMIZATION 193 | fi 194 | 195 | # Keep files to be backup/restored at the end of the helper 196 | # Assuming $dest_dir already exists 197 | if [ -n "$keep" ]; then 198 | local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID} 199 | local stuff_to_keep 200 | for stuff_to_keep in $keep; do 201 | if [ -e "$keep_dir/$stuff_to_keep" ]; then 202 | mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")" 203 | 204 | # We add "--no-target-directory" (short option is -T) to handle the special case 205 | # when we "keep" a folder, but then the new setup already contains the same dir (but possibly empty) 206 | # in which case a regular "cp" will create a copy of the directory inside the directory ... 207 | # resulting in something like /var/www/$app/data/data instead of /var/www/$app/data 208 | # cf https://unix.stackexchange.com/q/94831 for a more elaborate explanation on the option 209 | cp --archive --no-target-directory "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep" 210 | fi 211 | done 212 | fi 213 | rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/ 214 | 215 | if [ -n "${install_dir:-}" ] && [ "$dest_dir" == "$install_dir" ]; then 216 | _ynh_apply_default_permissions $dest_dir 217 | fi 218 | } 219 | -------------------------------------------------------------------------------- /scripts/upgrade: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./_common.sh 9 | source ./ynh_setup_source 10 | 11 | installed_version="${YNH_APP_CURRENT_VERSION/~ynh*/}" 12 | 13 | ensure_vars_set 14 | 15 | if [ "$YNH_APP_CURRENT_VERSION" == '-' ] || ynh_app_upgrading_from_version_before_or_equal_to '7.0~ynh1'; then 16 | ynh_die "Upgrade from this version not supported" 17 | fi 18 | 19 | ynh_script_progression "Stoping services..." 20 | 21 | ynh_systemctl --service="$app" --action=stop 22 | ynh_systemctl --service=seahub --action=stop 23 | ynh_systemctl --service="$app"-notification.service --action=stop 24 | ynh_systemctl --service="$app"-doc-server.service --action=stop 25 | ynh_systemctl --service="$app"-doc-converter.service --action=stop 26 | sleep 5 27 | pkill -f seafile-controller || true 28 | pkill -f seaf-server || true 29 | pkill -f ccnet-server || true 30 | pkill -f seahub || true 31 | 32 | # Migrate DB name if needed 33 | if mysqlshow | grep -q seafiledb; then 34 | mysqlconn="mysql -u root" 35 | sql_mv_params=$($mysqlconn -N -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES \ 36 | WHERE table_schema='seafiledb'") 37 | for name in $sql_mv_params; do 38 | $mysqlconn -e "RENAME TABLE seafiledb.$name to $db_name.$name"; 39 | done; 40 | $mysqlconn -e "DROP DATABASE seafiledb" 41 | ynh_replace --match='db_name = seafiledb' --replace='db_name = seafile' --file="$install_dir"/conf/seafile.conf 42 | sed -i "s|password\s*=\s*.*^|password = $db_pwd|g" "$install_dir"/conf/seafile.conf 43 | fi 44 | 45 | # Set missing settings 46 | ynh_app_setting_set_default --key=seahub_secret_key --value="$(grep -P 'SECRET_KEY\s*=\s*".+"' "$install_dir"/conf/seahub_settings.py | cut -d'"' -f2)" 47 | 48 | # 49 | # Update data dir if needed 50 | # 51 | 52 | # Move if needed old /home/yunohost.app/seafile-data dir to /home/yunohost.app/seafile/seafile-data 53 | if [ -e /home/yunohost.app/seafile-data ]; then 54 | if [ -e "$data_dir" ]; then 55 | mv "$data_dir" "${data_dir}_$(date '+%Y%m%d.%H%M%S')" 56 | fi 57 | mkdir -p "$data_dir" 58 | mv /home/yunohost.app/seafile-data "$data_dir"/ 59 | fi 60 | 61 | # In case of seafile-data content was directly stored in /home/yunohost.app/seafile 62 | if [ -e "$data_dir"/storage ]; then 63 | mkdir -p "$data_dir"/seafile-data 64 | mv -t "$data_dir"/seafile-data "$data_dir"/{commits,fs,httptemp,library-template,storage,tmpfiles,webdavtmp} || true # In case of some of dir don't exist 65 | fi 66 | 67 | # Move seahub data to /home/yunohost.app/seafile/seahub-data 68 | if [ -e "$install_dir"/seahub-data ] && [ ! -L "$install_dir"/seahub-data ]; then 69 | if [ -e "$data_dir"/seahub-data ]; then 70 | mv "$data_dir"/seahub-data "$data_dir/seahub-data_$(date '+%Y%m%d.%H%M%S')" 71 | fi 72 | mv "$install_dir"/seahub-data "$data_dir"/ 73 | fi 74 | 75 | # Move logs storage to /var/log/seafile 76 | if [ -e "$install_dir"/logs ] && [ ! -L "$install_dir"/logs ]; then 77 | if [ -e /var/log/"$app" ]; then 78 | mv /var/log/"$app" /var/log/"${app}_$(date '+%Y%m%d.%H%M%S')" 79 | fi 80 | mv "$install_dir"/logs /var/log/"${app}" 81 | fi 82 | 83 | if [ -z "${redis_db:-}" ]; then 84 | redis_db=$(ynh_redis_get_free_db) 85 | ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db" 86 | fi 87 | 88 | # Ensure all data dir are created 89 | mkdir -p /var/log/"$app" 90 | mkdir -p "$data_dir"/{seafile-data,seahub-data,notification-data} 91 | mkdir -p "$install_dir"/{conf,ccnet,seadoc-conf} 92 | 93 | ynh_script_progression "Upgrading source files..." 94 | 95 | # Download new version from sources 96 | ynh_script_progression "Installing sources files..." 97 | if [ "$YNH_APP_UPGRADE_TYPE" == UPGRADE_APP ]; then 98 | install_source 99 | fi 100 | 101 | ynh_script_progression "Configuring application..." 102 | 103 | # permission to execute update script and expect helper 104 | set_permission 105 | 106 | configure_env_files 107 | 108 | # do the upgrade ( the ";&" syntax mean when it go in the first case which is true it do all the next case) 109 | case "$installed_version" in 110 | "4."* ) 111 | # Update seafile by script 112 | ynh_die "Upgrade form the version 4.x was removed. Upgrade from this version won't be supported any more." 113 | ;& 114 | "5."* ) 115 | # Update Seafile by script 116 | ynh_die "Upgrade form the version 5.x was removed. Upgrade from this version won't be supported any more." 117 | ;& 118 | "6."* ) 119 | ynh_die "Upgrade form the version 6.x was removed. Upgrade from this version won't be supported any more." 120 | ;& 121 | "7.0"* ) 122 | # Fix file comment 123 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/seahub.sh" python-env python3 "/opt/seafile/seafile-server-$seafile_version/seahub/manage.py" migrate_file_comment 124 | 125 | # Update Seafile by script 126 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_7.0_7.1.sh" 127 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_7.0_7.1.sh" 128 | 129 | # Fix seafile data link. Look like that the upgrade script of seafile don't always work correctly 130 | if [ -e "$install_dir"/seafile-data ]; then 131 | old_data_dir_path="$install_dir/seafile-data$(date '+%Y%m%d.%H%M%S')" 132 | mv "$install_dir/seafile-data" "$old_data_dir_path" 133 | fi 134 | ln -s "$data_dir" "$install_dir"/seafile-data 135 | ;& 136 | "7.1."* ) 137 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_7.1_8.0.sh" 138 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_7.1_8.0.sh" 139 | ;& 140 | "8."* ) 141 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_8.0_9.0.sh" 142 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_8.0_9.0.sh" 143 | ;& 144 | "9."* ) 145 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_9.0_10.0.sh" 146 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_9.0_10.0.sh" 147 | ;& 148 | "10."* ) 149 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_10.0_11.0.sh" 150 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_10.0_11.0.sh" 151 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/seahub.sh" python-env python3 "/opt/seafile/seafile-server-$seafile_version/migrate_ldapusers.py" 152 | ;& 153 | "11."* ) 154 | ynh_safe_rm "$install_dir"/conf/ccnet.conf 155 | 156 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_11.0_12.0.sh" 157 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_11.0_12.0.sh" 158 | ;& 159 | esac 160 | 161 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/minor-upgrade.sh" 162 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/minor-upgrade.sh" 163 | 164 | # Clean expired sessions, cf: https://manual.seafile.com/12.0/administration/clean_database/ 165 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version//seahub.sh" python-env python3 seahub/manage.py clearsessions 166 | 167 | # Clean URL in config in DB 168 | clean_url_in_db_config 169 | 170 | # Update Seafile config files 171 | if [ "$(lsb_release -c -s)" == bullseye ]; then 172 | # Fix header for retro compability on YunoHost 11 173 | ynh_replace --match="'HTTP_YNH_USER_EMAIL'" --replace="'HTTP_EMAIL'" --file="../conf/seahub_settings.py" 174 | fi 175 | ynh_config_add --jinja --template=seahub_settings.py --destination="$install_dir"/conf/seahub_settings.py 176 | ynh_config_add --template=seafile.conf --destination="$install_dir"/conf/seafile.conf 177 | ynh_config_add --template=gunicorn.conf.py --destination="$install_dir"/conf/gunicorn.conf.py 178 | ynh_config_add --template=seafdav.conf --destination="$install_dir"/conf/seafdav.conf 179 | ynh_config_add --template=seafevents.conf --destination="$install_dir"/conf/seafevents.conf 180 | 181 | # Fix local warning 182 | ynh_replace --match=en_US.UTF-8 --replace="${LANG:-'en_US.UTF-8'}" --file="$seafile_code/seahub.sh" 183 | 184 | #================================================= 185 | 186 | # Config NGINX 187 | ynh_config_add_nginx 'seahub_port fileserver_port webdav_port' 188 | 189 | # Add Seafile Server to startup 190 | ynh_script_progression "Configuring $app's systemd service..." 191 | configure_systemd_services 192 | 193 | # register YunoHost service 194 | yunohost service add "$app" --description 'Main service for seafile server.' 195 | yunohost service add seahub --description 'Seafile server web interface.' 196 | yunohost service add "$app"-notification --description 'Seafile client notification server.' 197 | yunohost service add "$app-doc-server" --description 'Seafile online collaborative document editor server.' 198 | yunohost service add "$app-doc-converter" --description 'Seafile online collaborative document editor converter.' 199 | if [ "$YNH_ARCH" != arm64 ]; then 200 | yunohost service add "$app-thumbnail" --description 'Server to create thumbnails for images, videos, PDFs and other file types.' 201 | fi 202 | 203 | #================================================= 204 | 205 | # Set all permissions 206 | ynh_script_progression "Protecting directory..." 207 | set_permission 208 | 209 | # Add logrotate 210 | ynh_script_progression "Configuring log rotation..." 211 | ynh_config_add_logrotate /var/log/"$app" 212 | 213 | # Add Fail2Ban 214 | ynh_script_progression "Configuring fail2ban..." 215 | ynh_config_add_fail2ban --logpath="$install_dir"/logs/seahub.log 216 | 217 | # delete Seafile cache 218 | 219 | # restart Seafile server 220 | ynh_script_progression "Starting seafile services..." 221 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 222 | sleep 2 223 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 224 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 225 | ynh_systemctl --service="$app"-doc-server.service --wait_until="server is serve on http://127.0.0.1" --log_path=systemd 226 | ynh_systemctl --service="$app"-doc-converter.service --log_path=systemd 227 | if [ "$YNH_ARCH" != arm64 ]; then 228 | ynh_systemctl --service="$app"-thumbnail.service --log_path=systemd 229 | fi 230 | 231 | # remove old version files 232 | ynh_script_progression "Cleaning system and updating settings..." 233 | for f in "$install_dir"/seafile-server-*;do 234 | if [[ ! "$f" =~ ${seafile_version//./\\.}|latest ]]; then 235 | ynh_safe_rm "$f" 236 | fi 237 | done 238 | 239 | ynh_script_progression "Upgrade of $app completed" 240 | -------------------------------------------------------------------------------- /conf/seahub_settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # WARNING: Don't edit this file. All change will be removed after each app upgrade 4 | 5 | SECRET_KEY = "{{ seahub_secret_key }}" 6 | 7 | DATABASES = { 8 | 'default': { 9 | 'ENGINE': 'django.db.backends.mysql', 10 | 'NAME': 'seahubdb', 11 | 'USER': '{{ db_user }}', 12 | 'PASSWORD': '{{ db_pwd }}', 13 | 'HOST': '127.0.0.1', 14 | 'PORT': '3306', 15 | 'OPTIONS': {'charset': 'utf8mb4'}, 16 | } 17 | } 18 | 19 | CACHES = { 20 | 'default': { 21 | 'BACKEND': 'django.core.cache.backends.redis.RedisCache', 22 | 'LOCATION': 'redis://127.0.0.1:6379/{{ redis_db }}', 23 | }, 24 | } 25 | 26 | FILE_SERVER_ROOT = "https://{{ domain }}/seafhttp" 27 | SERVE_STATIC = False 28 | MEDIA_URL = "{{ path2 }}media/" 29 | COMPRESS_URL = MEDIA_URL 30 | STATIC_URL = MEDIA_URL + 'assets/' 31 | LOGIN_URL = '{{ path2 }}accounts/login/' 32 | 33 | # 34 | # LDAP 35 | # 36 | 37 | ENABLE_LDAP = True 38 | 39 | # The URL of LDAP server 40 | LDAP_SERVER_URL = 'ldap://127.0.0.1:389' 41 | 42 | # The root node of users who can log in to Seafile in the LDAP server 43 | LDAP_BASE_DN = 'ou=users,dc=yunohost,dc=org' 44 | 45 | # DN of the administrator used to query the LDAP server for information. 46 | # For OpenLDAP, it maybe cn=admin,dc=example,dc=com 47 | LDAP_ADMIN_DN = '' # Need to leave empty to work with anonymous authentication 48 | 49 | # Password of LDAP_ADMIN_DN 50 | LDAP_ADMIN_PASSWORD = '' # Need to leave empty to work with anonymous authentication 51 | 52 | # Identify the source of the user, used in 53 | # the table social_auth_usersocialauth, defaults to 'ldap' 54 | LDAP_PROVIDER = 'ldap' 55 | 56 | # User's attribute used to log in to Seafile. 57 | # It should be a unique identifier for the user in LDAP server. 58 | # Learn more about this id from the descriptions at begining of this section. 59 | LDAP_LOGIN_ATTR = 'mail' 60 | 61 | # LDAP user's contact_email attribute 62 | LDAP_CONTACT_EMAIL_ATTR = 'mail' 63 | 64 | # LDAP user's role attribute 65 | LDAP_USER_ROLE_ATTR = '' 66 | 67 | # For sync user's first name 68 | LDAP_USER_FIRST_NAME_ATTR = 'givenName' 69 | 70 | # For sync user's last name 71 | LDAP_USER_LAST_NAME_ATTR = 'sn' 72 | 73 | # Whether to reverse the user's first and last name 74 | LDAP_USER_NAME_REVERSE = False 75 | 76 | # Additional filter conditions, users who meet the filter conditions can log in, otherwise they cannot log in 77 | LDAP_FILTER = 'permission=cn={{ app }}.main,ou=permission,dc=yunohost,dc=org' 78 | 79 | # 80 | # SSO 81 | # 82 | 83 | ENABLE_REMOTE_USER_AUTHENTICATION = True 84 | 85 | # Optional, HTTP header, which is configured in your web server conf file, 86 | # used for Seafile to get user's unique id, default value is 'HTTP_REMOTE_USER'. 87 | REMOTE_USER_HEADER = 'HTTP_YNH_USER_EMAIL' 88 | 89 | # Optional, when the value of HTTP_REMOTE_USER is not a valid email address, 90 | # Seafile will build a email-like unique id from the value of 'REMOTE_USER_HEADER' 91 | # and this domain, e.g. user1@example.com. 92 | # REMOTE_USER_DOMAIN = 'example.com' 93 | 94 | # Optional, whether to create new user in Seafile system, default value is True. 95 | # If this setting is disabled, users doesn't preexist in the Seafile DB cannot login. 96 | # The admin has to first import the users from external systems like LDAP. 97 | REMOTE_USER_CREATE_UNKNOWN_USER = False 98 | 99 | # Optional, whether to activate new user in Seafile system, default value is True. 100 | # If this setting is disabled, user will be unable to login by default. 101 | # the administrator needs to manually activate this user. 102 | # REMOTE_USER_ACTIVATE_USER_AFTER_CREATION = True 103 | 104 | # Optional, map user attribute in HTTP header and Seafile's user attribute. 105 | # REMOTE_USER_ATTRIBUTE_MAP = { 106 | # 'HTTP_DISPLAYNAME': 'name', 107 | # 'HTTP_EMAIL': 'contact_email', 108 | # 109 | # # for user info 110 | # "HTTP_GIVENNAME": 'givenname', 111 | # "HTTP_SN": 'surname', 112 | # } 113 | REMOTE_USER_PROTECTED_PATH = ['{{ path }}', '{{ path2 }}accounts/login', '{{ path2 }}sso'] 114 | REMOTE_USER_IMPORT_FROM_LDAP = True 115 | 116 | # 117 | # Security settings 118 | # 119 | 120 | # For security consideration, please set to match the host/domain of your site, e.g., ALLOWED_HOSTS = ['.example.com']. 121 | # Please refer https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts for details. 122 | ALLOWED_HOSTS = ['{{ domain }}', '127.0.0.1'] 123 | 124 | # Whether to use a secure cookie for the CSRF cookie 125 | # https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-secure 126 | CSRF_COOKIE_SECURE = True 127 | 128 | # The value of the SameSite flag on the CSRF cookie 129 | # https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-samesite 130 | CSRF_COOKIE_SAMESITE = 'Strict' 131 | 132 | # https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-trusted-origins 133 | CSRF_TRUSTED_ORIGINS = ['https://{{ domain }}'] 134 | 135 | # 136 | # User options 137 | # 138 | 139 | # Enalbe or disalbe registration on web. Default is `False`. 140 | # ENABLE_SIGNUP = False 141 | 142 | # Activate or deactivate user when registration complete. Default is `True`. 143 | # If set to `False`, new users need to be activated by admin in admin panel. 144 | # ACTIVATE_AFTER_REGISTRATION = True 145 | 146 | # Whether to send email when a system admin adding a new member. Default is `True`. 147 | # SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER = True 148 | 149 | # Whether to send email when a system admin resetting a user's password. Default is `True`. 150 | # SEND_EMAIL_ON_RESETTING_USER_PASSWD = True 151 | 152 | # Send system admin notify email when user registration is complete. Default is `False`. 153 | # NOTIFY_ADMIN_AFTER_REGISTRATION = False 154 | 155 | # Remember days for login. Default is 7 156 | # LOGIN_REMEMBER_DAYS = 7 157 | 158 | # Attempt limit before showing a captcha when login. 159 | # LOGIN_ATTEMPT_LIMIT = 3 160 | 161 | # deactivate user account when login attempts exceed limit 162 | # Since version 5.1.2 or pro 5.1.3 163 | # FREEZE_USER_ON_LOGIN_FAILED = False 164 | 165 | # Age of cookie, in seconds (default: 2 weeks). 166 | # SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 167 | 168 | # Whether a user's session cookie expires when the Web browser is closed. 169 | # SESSION_EXPIRE_AT_BROWSER_CLOSE = False 170 | 171 | # Whether to save the session data on every request. Default is `False` 172 | # SESSION_SAVE_EVERY_REQUEST = False 173 | 174 | # Whether enable the feature "published library". Default is `False` 175 | # Since 6.1.0 CE 176 | ENABLE_WIKI = True 177 | 178 | # In old version, if you use Single Sign On, the password is not saved in Seafile. 179 | # Users can't use WebDAV because Seafile can't check whether the password is correct. 180 | # Since version 6.3.8, you can enable this option to let user's to specific a password for WebDAV login. 181 | # Users login via SSO can use this password to login in WebDAV. 182 | # Enable the feature. pycryptodome should be installed first. 183 | # sudo pip install pycryptodome==3.12.0 184 | ENABLE_WEBDAV_SECRET = True 185 | WEBDAV_SECRET_MIN_LENGTH = 20 186 | 187 | # LEVEL for the password, based on four types of input: 188 | # num, upper letter, lower letter, other symbols 189 | # '3' means password must have at least 3 types of the above. 190 | WEBDAV_SECRET_STRENGTH_LEVEL = 3 191 | 192 | # Since version 7.0.9, you can force a full user to log in with a two factor authentication. 193 | # The prerequisite is that the administrator should 'enable two factor authentication' in the 'System Admin -> Settings' page. 194 | # Then you can add the following configuration information to the configuration file. 195 | # ENABLE_FORCE_2FA_TO_ALL_USERS = False 196 | 197 | # 198 | # Library options 199 | # 200 | 201 | # if enable create encrypted library 202 | # ENABLE_ENCRYPTED_LIBRARY = True 203 | 204 | # version for encrypted library 205 | # should only be `2` or `4`. 206 | # version 3 is insecure (using AES128 encryption) so it's not recommended any more. 207 | # ENCRYPTED_LIBRARY_VERSION = 2 208 | 209 | # mininum length for password of encrypted library 210 | # REPO_PASSWORD_MIN_LENGTH = 8 211 | 212 | # force use password when generate a share/upload link (since version 8.0.9) 213 | # SHARE_LINK_FORCE_USE_PASSWORD = False 214 | 215 | # mininum length for password for share link (since version 4.4) 216 | # SHARE_LINK_PASSWORD_MIN_LENGTH = 8 217 | 218 | # LEVEL for the password of a share/upload link 219 | # based on four types of input: 220 | # num, upper letter, lower letter, other symbols 221 | # '3' means password must have at least 3 types of the above. (since version 8.0.9) 222 | # SHARE_LINK_PASSWORD_STRENGTH_LEVEL = 3 223 | 224 | # Default expire days for share link (since version 6.3.8) 225 | # Once this value is configured, the user can no longer generate an share link with no expiration time. 226 | # If the expiration value is not set when the share link is generated, the value configured here will be used. 227 | # SHARE_LINK_EXPIRE_DAYS_DEFAULT = 5 228 | 229 | # minimum expire days for share link (since version 6.3.6) 230 | # SHARE_LINK_EXPIRE_DAYS_MIN should be less than SHARE_LINK_EXPIRE_DAYS_DEFAULT (If the latter is set). 231 | # SHARE_LINK_EXPIRE_DAYS_MIN = 3 # default is 0, no limit. 232 | 233 | # maximum expire days for share link (since version 6.3.6) 234 | # SHARE_LINK_EXPIRE_DAYS_MIN should be greater than SHARE_LINK_EXPIRE_DAYS_DEFAULT (If the latter is set). 235 | # SHARE_LINK_EXPIRE_DAYS_MAX = 8 # default is 0, no limit. 236 | 237 | # Default expire days for upload link (since version 7.1.6) 238 | # Once this value is configured, the user can no longer generate an upload link with no expiration time. 239 | # If the expiration value is not set when the upload link is generated, the value configured here will be used. 240 | # UPLOAD_LINK_EXPIRE_DAYS_DEFAULT = 5 241 | 242 | # minimum expire days for upload link (since version 7.1.6) 243 | # UPLOAD_LINK_EXPIRE_DAYS_MIN should be less than UPLOAD_LINK_EXPIRE_DAYS_DEFAULT (If the latter is set). 244 | # UPLOAD_LINK_EXPIRE_DAYS_MIN = 3 # default is 0, no limit. 245 | 246 | # maximum expire days for upload link (since version 7.1.6) 247 | # UPLOAD_LINK_EXPIRE_DAYS_MAX should be greater than UPLOAD_LINK_EXPIRE_DAYS_DEFAULT (If the latter is set). 248 | # UPLOAD_LINK_EXPIRE_DAYS_MAX = 8 # default is 0, no limit. 249 | 250 | # force user login when view file/folder share link (since version 6.3.6) 251 | # SHARE_LINK_LOGIN_REQUIRED = False 252 | 253 | # enable water mark when view(not edit) file in web browser (since version 6.3.6) 254 | # ENABLE_WATERMARK = True 255 | 256 | # Disable sync with any folder. Default is `False` 257 | # NOTE: since version 4.2.4 258 | # DISABLE_SYNC_WITH_ANY_FOLDER = False 259 | 260 | # Enable or disable library history setting 261 | # ENABLE_REPO_HISTORY_SETTING = True 262 | 263 | # Enable or disable normal user to create organization libraries 264 | # Since version 5.0.5 265 | # ENABLE_USER_CREATE_ORG_REPO = True 266 | 267 | # Enable or disable user share library to any group 268 | # Since version 6.2.0 269 | # ENABLE_SHARE_TO_ALL_GROUPS = True 270 | 271 | # Enable or disable user to clean trash (default is True) 272 | # Since version 6.3.6 273 | # ENABLE_USER_CLEAN_TRASH = True 274 | 275 | # Add a report abuse button on download links. (since version 7.1.0) 276 | # Users can report abuse on the share link page, fill in the report type, contact information, and description. 277 | # Default is false. 278 | # ENABLE_SHARE_LINK_REPORT_ABUSE = False 279 | 280 | # 281 | # Online preview 282 | # 283 | 284 | # Whether to use pdf.js to view pdf files online. Default is `True`, you can turn it off. 285 | # NOTE: since version 1.4. 286 | # USE_PDFJS = True 287 | 288 | # Online preview maximum file size, defaults to 30M. 289 | # FILE_PREVIEW_MAX_SIZE = 30 * 1024 * 1024 290 | 291 | # Extensions of previewed text files. 292 | # NOTE: since version 6.1.1 293 | # TEXT_PREVIEW_EXT = """ac, am, bat, c, cc, cmake, cpp, cs, css, diff, el, h, html, 294 | # htm, java, js, json, less, make, org, php, pl, properties, py, rb, 295 | # scala, script, sh, sql, txt, text, tex, vi, vim, xhtml, xml, log, csv, 296 | # groovy, rst, patch, go""" 297 | 298 | # Enable or disable thumbnails 299 | # NOTE: since version 4.0.2 300 | ENABLE_THUMBNAIL = True 301 | 302 | # Seafile only generates thumbnails for images smaller than the following size. 303 | # Since version 6.3.8 pro, suport the psd online preview. 304 | # THUMBNAIL_IMAGE_SIZE_LIMIT = 30 # MB 305 | 306 | # video thumbnails 307 | ENABLE_VIDEO_THUMBNAIL = True 308 | 309 | # Use the frame at 5 second as thumbnail 310 | # NOTE: this option is deprecated in version 7.1 311 | # THUMBNAIL_VIDEO_FRAME_TIME = 5 312 | 313 | # Absolute filesystem path to the directory that will hold thumbnail files. 314 | # THUMBNAIL_ROOT = '/haiwen/seahub-data/thumbnail/thumb/' 315 | 316 | # Default size for picture preview. Enlarge this size can improve the preview quality. 317 | # NOTE: since version 6.1.1 318 | # THUMBNAIL_SIZE_FOR_ORIGINAL = 1024 319 | 320 | # 321 | # Other options 322 | # 323 | 324 | # This is outside URL for Seahub(Seafile Web). 325 | # The domain part (i.e., www.example.com) will be used in generating share links and download/upload file via web. 326 | # Note: Outside URL means "if you use Nginx, it should be the Nginx's address" 327 | # Note: SERVICE_URL is moved to seahub_settings.py since 9.0.0 328 | SERVICE_URL = "https://{{ domain }}{{ path }}" 329 | 330 | # Disable settings via Web interface in system admin->settings 331 | # Default is True 332 | # Since 5.1.3 333 | # ENABLE_SETTINGS_VIA_WEB = True 334 | 335 | # Choices can be found here: 336 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 337 | # although not all choices may be available on all operating systems. 338 | # If running in a Windows environment this must be set to the same as your 339 | # system time zone. 340 | TIME_ZONE = "{{ time_zone }}" 341 | 342 | # Language code for this installation. All choices can be found here: 343 | # http://www.i18nguy.com/unicode/language-identifiers.html 344 | # Default language for sending emails. 345 | LANGUAGE_CODE = '{{ language }}' 346 | 347 | # Custom language code choice. 348 | # LANGUAGES = ( ) 349 | 350 | # Set this to your website/company's name. This is contained in email notifications and welcome message when user login for the first time. 351 | SITE_NAME = 'Seafile' 352 | 353 | # Browser tab's title 354 | SITE_TITLE = 'Private Seafile' 355 | 356 | # If you don't want to run seahub website on your site's root path, set this option to your preferred path. 357 | # e.g. setting it to '/seahub/' would run seahub on http://example.com/seahub/. 358 | SITE_ROOT = "{{ path2 }}" 359 | 360 | # Max number of files when user upload file/folder. 361 | # Since version 6.0.4 362 | # MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD = 500 363 | 364 | # Control the language that send email. Default to user's current language. 365 | # Since version 6.1.1 366 | # SHARE_LINK_EMAIL_LANGUAGE = '' 367 | 368 | # Interval for browser requests unread notifications 369 | # Since PRO 6.1.4 or CE 6.1.2 370 | # UNREAD_NOTIFICATIONS_REQUEST_INTERVAL = 3 * 60 # seconds 371 | 372 | # Get web api auth token on profile page. 373 | # ENABLE_GET_AUTH_TOKEN_BY_SESSION = True 374 | 375 | # Since 8.0.6 CE/PRO version. 376 | # Url redirected to after user logout Seafile. 377 | # Usually configured as Single Logout url. 378 | LOGOUT_REDIRECT_URL = 'https://{{ domain }}/yunohost/sso/?action=logout' 379 | 380 | # Enable system admin add T&C, all users need to accept terms before using. Defaults to `False`. 381 | # Since version 6.0 382 | # ENABLE_TERMS_AND_CONDITIONS = False 383 | 384 | # Enable two factor authentication for accounts. Defaults to `False`. 385 | # Since version 6.0 386 | # ENABLE_TWO_FACTOR_AUTH = False 387 | 388 | # Enable user select a template when he/she creates library. 389 | # When user select a template, Seafile will create folders releated to the pattern automaticly. 390 | # Since version 6.0 391 | # LIBRARY_TEMPLATES = { 392 | # 'Technology': ['/Develop/Python', '/Test'], 393 | # 'Finance': ['/Current assets', '/Fixed assets/Computer'] 394 | # } 395 | 396 | # Enable a user to change password in 'settings' page. Default to `True` 397 | # Since version 6.2.11 398 | # ENABLE_CHANGE_PASSWORD = True 399 | 400 | # If show contact email when search user. 401 | # ENABLE_SHOW_CONTACT_EMAIL_WHEN_SEARCH_USER = True 402 | 403 | # 404 | # Mail 405 | # 406 | 407 | EMAIL_USE_TLS = True 408 | EMAIL_HOST = "{{ domain }}" 409 | EMAIL_HOST_USER = "{{ app }}" 410 | EMAIL_HOST_PASSWORD = "{{ mail_pwd }}" 411 | EMAIL_PORT = "587" 412 | REPLACE_FROM_EMAIL = True 413 | ADD_REPLY_TO_HEADER = True 414 | DEFAULT_FROM_EMAIL = "{{ app }}@{{ domain }}" 415 | SERVER_EMAIL = "{{ app }}@{{ domain }}" 416 | 417 | # 418 | # RESTful API 419 | # 420 | 421 | # API throttling related settings. Enlarger the rates if you got 429 response code during API calls. 422 | # REST_FRAMEWORK = { 423 | # 'DEFAULT_THROTTLE_RATES': { 424 | # 'ping': '600/minute', 425 | # 'anon': '5/minute', 426 | # 'user': '300/minute', 427 | # }, 428 | # 'UNICODE_JSON': False, 429 | # } 430 | 431 | # Throtting whitelist used to disable throttle for certain IPs. 432 | # e.g. REST_FRAMEWORK_THROTTING_WHITELIST = ['127.0.0.1', '192.168.1.1'] 433 | # Please make sure `REMOTE_ADDR` header is configured in Nginx conf according to https://manual.seafile.com/deploy/deploy_with_nginx.html. 434 | # REST_FRAMEWORK_THROTTING_WHITELIST = [] 435 | --------------------------------------------------------------------------------