├── .gitattributes ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── LICENSE ├── README.md ├── auto_update ├── auto_update.sh └── auto_update_config_example.sh ├── conf ├── create_admin.json ├── f2b_filter.conf ├── f2b_jail.conf ├── gunicorn.conf.py ├── nginx.conf ├── notification_server_env.j2 ├── seafdav.conf ├── seafevents.conf ├── seafile-notification.service ├── seafile.conf ├── seafile.service ├── seafile_env.j2 ├── seahub.service └── seahub_settings.py ├── doc ├── ADMIN.md ├── DESCRIPTION.md ├── DESCRIPTION_fr.md ├── POST_UPGRADE.md └── screenshots │ └── screenshot.png ├── manifest.toml ├── patches └── main │ └── import_ldap_user_when_authenticated_from_remoteUserBackend.patch ├── scripts ├── _common.sh ├── backup ├── change_url ├── experimental_helper.sh ├── install ├── remove ├── restore ├── upgrade └── ynh_setup_source └── tests.toml /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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: 12.0.11~ynh3](https://img.shields.io/badge/Version-12.0.11~ynh3-rgba(0,150,0,1)?style=for-the-badge)](https://ci-apps.yunohost.org/ci/apps/seafile/) 16 | 17 |
18 | 19 | 20 |
21 | 22 | ## 📦 Developer info 23 | 24 | [![Automatic tests level](https://apps.yunohost.org/badge/cilevel/seafile)](https://ci-apps.yunohost.org/ci/apps/seafile/) 25 | 26 | 🛠️ Upstream Seafile repository: 27 | 28 | Pull request are welcome and should target the [`testing` branch](https://github.com/YunoHost-Apps/seafile_ynh/tree/testing). 29 | 30 | The `testing` branch can be tested using: 31 | ``` 32 | # fresh install: 33 | sudo yunohost app install https://github.com/YunoHost-Apps/seafile_ynh/tree/testing 34 | 35 | # upgrade an existing install: 36 | sudo yunohost app upgrade seafile -u https://github.com/YunoHost-Apps/seafile_ynh/tree/testing 37 | ``` 38 | 39 | ### 📚 App packaging documentation 40 | 41 | Please see for more information. -------------------------------------------------------------------------------- /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" 84 | return "${PIPESTATUS[0]}" 85 | } 86 | 87 | app_prev_version="$(get_from_manifest ".version" | cut -d'~' -f1)" 88 | app_version="$app_prev_version" 89 | 90 | if check_app_version 91 | then 92 | set +eu 93 | upgrade_app 94 | res=$? 95 | set -eu 96 | if [ $res -eq 0 ]; then 97 | result="Success" 98 | else 99 | result="Failed" 100 | fi 101 | msg="Build: $app_name version $app_version" 102 | 103 | echo "$msg" | mail.mailutils --content-type="text/plain; charset=UTF-8" -A "${app_name}_build_temp.log" -s "Autoupgrade $app_name : $result" "$notify_email" 104 | fi 105 | -------------------------------------------------------------------------------- /auto_update/auto_update_config_example.sh: -------------------------------------------------------------------------------- 1 | notify_email="hello@world.tld" 2 | -------------------------------------------------------------------------------- /conf/create_admin.json: -------------------------------------------------------------------------------- 1 | {"email": "__ADMIN__", "password": "__PASSWORD__"} 2 | -------------------------------------------------------------------------------- /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/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/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 | access_log /var/log/nginx/seahub.access.log; 14 | error_log /var/log/nginx/seahub.error.log; 15 | 16 | include conf.d/yunohost_panel.conf.inc; 17 | } 18 | 19 | location __PATH__/media/ { 20 | alias __SEAFILE_CODE__/seahub/media/; 21 | } 22 | 23 | location __PATH__/media/avatars/ { 24 | alias __DATA_DIR__/seahub-data/avatars/; 25 | } 26 | 27 | location /seafhttp/ { 28 | proxy_pass http://127.0.0.1:__PORT_FILESERVER__/; 29 | proxy_connect_timeout 36000s; 30 | proxy_read_timeout 36000s; 31 | proxy_send_timeout 36000s; 32 | 33 | client_max_body_size 0; 34 | proxy_request_buffering off; 35 | 36 | access_log /var/log/nginx/seafhttp.access.log; 37 | error_log /var/log/nginx/seafhttp.error.log; 38 | } 39 | 40 | location /notification/ping { 41 | proxy_pass http://127.0.0.1:8083/ping; 42 | access_log /var/log/nginx/seafile-notification.access.log; 43 | error_log /var/log/nginx/seafile-notification.error.log; 44 | } 45 | 46 | location /notification { 47 | proxy_pass http://127.0.0.1:8083/; 48 | proxy_http_version 1.1; 49 | proxy_set_header Upgrade $http_upgrade; 50 | proxy_set_header Connection "upgrade"; 51 | access_log /var/log/nginx/seafile-notification.access.log; 52 | error_log /var/log/nginx/seafile-notification.error.log; 53 | } 54 | 55 | location /seafdav { 56 | rewrite ^/seafdav$ /seafdav/ permanent; 57 | } 58 | 59 | location /seafdav/ { 60 | proxy_pass http://127.0.0.1:__PORT_WEBDAV__/seafdav/; 61 | proxy_set_header Host $host; 62 | proxy_set_header X-Real-IP $remote_addr; 63 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 64 | proxy_set_header X-Forwarded-Host $server_name; 65 | proxy_set_header X-Forwarded-Proto $scheme; 66 | 67 | proxy_read_timeout 1200s; 68 | client_max_body_size 0; 69 | proxy_request_buffering off; 70 | 71 | access_log /var/log/nginx/seafdav.access.log; 72 | error_log /var/log/nginx/seafdav.error.log; 73 | } 74 | -------------------------------------------------------------------------------- /conf/notification_server_env.j2: -------------------------------------------------------------------------------- 1 | SEAFILE_MYSQL_DB_HOST=127.0.0.1 2 | SEAFILE_MYSQL_DB_PORT=3306 3 | SEAFILE_MYSQL_DB_USER={{ db_user }} 4 | SEAFILE_MYSQL_DB_PASSWORD={{ db_pwd }} 5 | SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnetdb 6 | SEAFILE_MYSQL_DB_SEAFILE_DB_NAME={{ db_name }} 7 | JWT_PRIVATE_KEY={{ jwt_private }} 8 | SEAFILE_LOG_TO_STDOUT=true 9 | NOTIFICATION_SERVER_LOG_LEVEL=info 10 | TIME_ZONE={{ time_zone }} 11 | SEAFILE_SERVER_PROTOCOL=https 12 | SEAFILE_SERVER_HOSTNAME={{ domain }} 13 | NOTIFICATION_SERVER_HOST=127.0.0.1 14 | NOTIFICATION_SERVER_PORT={{ port_notificationserver }} 15 | -------------------------------------------------------------------------------- /conf/seafdav.conf: -------------------------------------------------------------------------------- 1 | [WEBDAV] 2 | enabled = true 3 | port = __PORT_WEBDAV__ 4 | share_name = /seafdav 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /conf/seafile-notification.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seafile notification server 3 | After=network.target 4 | After=mysql.service 5 | 6 | [Service] 7 | Type=simple 8 | ExecStart=/opt/seafile/notification-server -c /opt/notification-data 9 | User=__APP__ 10 | Group=__APP__ 11 | 12 | # Config releated to run in docker provied file system 13 | RootDirectory=__INSTALL_DIR__/notification_image 14 | BindPaths=__SYSTEMD_NOTIFICATION_SERVER_BIND_MOUNT__ 15 | EnvironmentFile=__INSTALL_DIR__/notification_server_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.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.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 | 13 | # Config releated to run in docker provied file system 14 | RootDirectory=__INSTALL_DIR__/seafile_image 15 | BindPaths=__SYSTEMD_SEAFILE_BIND_MOUNT__ 16 | EnvironmentFile=__INSTALL_DIR__/seafile_env.conf 17 | 18 | # Sandboxing options to harden security 19 | # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html 20 | NoNewPrivileges=yes 21 | PrivateTmp=yes 22 | PrivateDevices=yes 23 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 24 | RestrictNamespaces=yes 25 | RestrictRealtime=yes 26 | DevicePolicy=closed 27 | ProtectSystem=full 28 | ProtectControlGroups=yes 29 | ProtectKernelModules=yes 30 | ProtectKernelTunables=yes 31 | LockPersonality=yes 32 | SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap 33 | 34 | # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html 35 | CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD 36 | CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE 37 | CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT 38 | CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK 39 | CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM 40 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG 41 | CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE 42 | CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW 43 | CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG 44 | 45 | [Install] 46 | WantedBy=multi-user.target 47 | -------------------------------------------------------------------------------- /conf/seafile_env.j2: -------------------------------------------------------------------------------- 1 | JWT_PRIVATE_KEY={{ jwt_private }} 2 | SEAFILE_SERVER_PROTOCOL=https 3 | SEAFILE_SERVER_HOSTNAME={{ domain }} 4 | SEAFILE_MYSQL_DB_HOST=127.0.0.1 5 | SEAFILE_MYSQL_DB_PORT=3306 6 | SEAFILE_MYSQL_DB_USER={{ db_user }} 7 | SEAFILE_MYSQL_DB_PASSWORD={{ db_pwd }} 8 | SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnetdb 9 | SEAFILE_MYSQL_DB_SEAFILE_DB_NAME={{ db_name }} 10 | SEAFILE_MYSQL_DB_SEAHUB_DB_NAME=seahubdb 11 | TIME_ZONE={{ time_zone }} 12 | SITE_ROOT={{ path2 }} 13 | -------------------------------------------------------------------------------- /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 releated to run in docker provied 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/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_pylibmc.memcached.PyLibMCCache', 22 | 'LOCATION': '127.0.0.1:11211', 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://localhost: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 | # Enable or disable thumbnail for video. ffmpeg and moviepy should be installed first. 307 | # For details, please refer to https://manual.seafile.com/deploy/video_thumbnails.html 308 | # NOTE: this option is deprecated in version 7.1 309 | # ENABLE_VIDEO_THUMBNAIL = False 310 | 311 | # Use the frame at 5 second as thumbnail 312 | # NOTE: this option is deprecated in version 7.1 313 | # THUMBNAIL_VIDEO_FRAME_TIME = 5 314 | 315 | # Absolute filesystem path to the directory that will hold thumbnail files. 316 | # THUMBNAIL_ROOT = '/haiwen/seahub-data/thumbnail/thumb/' 317 | 318 | # Default size for picture preview. Enlarge this size can improve the preview quality. 319 | # NOTE: since version 6.1.1 320 | # THUMBNAIL_SIZE_FOR_ORIGINAL = 1024 321 | 322 | # 323 | # Other options 324 | # 325 | 326 | # This is outside URL for Seahub(Seafile Web). 327 | # The domain part (i.e., www.example.com) will be used in generating share links and download/upload file via web. 328 | # Note: Outside URL means "if you use Nginx, it should be the Nginx's address" 329 | # Note: SERVICE_URL is moved to seahub_settings.py since 9.0.0 330 | SERVICE_URL = "https://{{ domain }}{{ path }}" 331 | 332 | # Disable settings via Web interface in system admin->settings 333 | # Default is True 334 | # Since 5.1.3 335 | # ENABLE_SETTINGS_VIA_WEB = True 336 | 337 | # Choices can be found here: 338 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 339 | # although not all choices may be available on all operating systems. 340 | # If running in a Windows environment this must be set to the same as your 341 | # system time zone. 342 | TIME_ZONE = "{{ time_zone }}" 343 | 344 | # Language code for this installation. All choices can be found here: 345 | # http://www.i18nguy.com/unicode/language-identifiers.html 346 | # Default language for sending emails. 347 | LANGUAGE_CODE = '{{ language }}' 348 | 349 | # Custom language code choice. 350 | # LANGUAGES = ( ) 351 | 352 | # Set this to your website/company's name. This is contained in email notifications and welcome message when user login for the first time. 353 | SITE_NAME = 'Seafile' 354 | 355 | # Browser tab's title 356 | SITE_TITLE = 'Private Seafile' 357 | 358 | # If you don't want to run seahub website on your site's root path, set this option to your preferred path. 359 | # e.g. setting it to '/seahub/' would run seahub on http://example.com/seahub/. 360 | SITE_ROOT = "{{ path2 }}" 361 | 362 | # Max number of files when user upload file/folder. 363 | # Since version 6.0.4 364 | # MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD = 500 365 | 366 | # Control the language that send email. Default to user's current language. 367 | # Since version 6.1.1 368 | # SHARE_LINK_EMAIL_LANGUAGE = '' 369 | 370 | # Interval for browser requests unread notifications 371 | # Since PRO 6.1.4 or CE 6.1.2 372 | # UNREAD_NOTIFICATIONS_REQUEST_INTERVAL = 3 * 60 # seconds 373 | 374 | # Get web api auth token on profile page. 375 | # ENABLE_GET_AUTH_TOKEN_BY_SESSION = True 376 | 377 | # Since 8.0.6 CE/PRO version. 378 | # Url redirected to after user logout Seafile. 379 | # Usually configured as Single Logout url. 380 | LOGOUT_REDIRECT_URL = 'https://{{ domain }}/yunohost/sso/?action=logout' 381 | 382 | # Enable system admin add T&C, all users need to accept terms before using. Defaults to `False`. 383 | # Since version 6.0 384 | # ENABLE_TERMS_AND_CONDITIONS = False 385 | 386 | # Enable two factor authentication for accounts. Defaults to `False`. 387 | # Since version 6.0 388 | # ENABLE_TWO_FACTOR_AUTH = False 389 | 390 | # Enable user select a template when he/she creates library. 391 | # When user select a template, Seafile will create folders releated to the pattern automaticly. 392 | # Since version 6.0 393 | # LIBRARY_TEMPLATES = { 394 | # 'Technology': ['/Develop/Python', '/Test'], 395 | # 'Finance': ['/Current assets', '/Fixed assets/Computer'] 396 | # } 397 | 398 | # Enable a user to change password in 'settings' page. Default to `True` 399 | # Since version 6.2.11 400 | # ENABLE_CHANGE_PASSWORD = True 401 | 402 | # If show contact email when search user. 403 | # ENABLE_SHOW_CONTACT_EMAIL_WHEN_SEARCH_USER = True 404 | 405 | # 406 | # Mail 407 | # 408 | 409 | EMAIL_USE_TLS = True 410 | EMAIL_HOST = "{{ domain }}" 411 | EMAIL_HOST_USER = "{{ app }}" 412 | EMAIL_HOST_PASSWORD = "{{ mail_pwd }}" 413 | EMAIL_PORT = "587" 414 | REPLACE_FROM_EMAIL = True 415 | ADD_REPLY_TO_HEADER = True 416 | DEFAULT_FROM_EMAIL = "{{ app }}@{{ domain }}" 417 | SERVER_EMAIL = "{{ app }}@{{ domain }}" 418 | 419 | # 420 | # RESTful API 421 | # 422 | 423 | # API throttling related settings. Enlarger the rates if you got 429 response code during API calls. 424 | # REST_FRAMEWORK = { 425 | # 'DEFAULT_THROTTLE_RATES': { 426 | # 'ping': '600/minute', 427 | # 'anon': '5/minute', 428 | # 'user': '300/minute', 429 | # }, 430 | # 'UNICODE_JSON': False, 431 | # } 432 | 433 | # Throtting whitelist used to disable throttle for certain IPs. 434 | # e.g. REST_FRAMEWORK_THROTTING_WHITELIST = ['127.0.0.1', '192.168.1.1'] 435 | # Please make sure `REMOTE_ADDR` header is configured in Nginx conf according to https://manual.seafile.com/deploy/deploy_with_nginx.html. 436 | # REST_FRAMEWORK_THROTTING_WHITELIST = [] 437 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/screenshots/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YunoHost-Apps/seafile_ynh/983b48296194287a00923a98c75abb9e7c4a282b/doc/screenshots/screenshot.png -------------------------------------------------------------------------------- /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 = "12.0.11~ynh3" 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 | ldap = true 26 | sso = true 27 | disk = "1.5G" 28 | ram.build = "0M" 29 | ram.runtime = "500M" 30 | 31 | [install] 32 | [install.domain] 33 | # this is a generic question - ask strings are automatically handled by Yunohost's core 34 | type = "domain" 35 | 36 | [install.path] 37 | # this is a generic question - ask strings are automatically handled by Yunohost's core 38 | type = "path" 39 | default = "/seafile" 40 | 41 | [install.server_name] 42 | ask.en = "Choose a name (3 - 15 letters or digits)" 43 | ask.fr = "Choisissez un nom (3 - 15 letters or digits)" 44 | type = "string" 45 | example = "Seafile" 46 | default = "Seafile" 47 | 48 | [install.admin] 49 | # this is a generic question - ask strings are automatically handled by Yunohost's core 50 | type = "user" 51 | 52 | [install.admin_password] 53 | ask.en = "Enter a password for the administrator" 54 | ask.fr = "Entrez un mot de passe pour l'administrateur" 55 | type = "password" 56 | 57 | [install.init_main_permission] 58 | 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." 59 | 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." 60 | type = "group" 61 | default = "visitors" 62 | 63 | [resources] 64 | [resources.system_user] 65 | allow_email = true 66 | 67 | [resources.install_dir] 68 | owner = "__APP__:rwx" 69 | group = "www-data:r-x" 70 | 71 | [resources.data_dir] 72 | dir = "/home/yunohost.app/__APP__" 73 | 74 | [resources.permissions] 75 | main.url = "/" 76 | 77 | file_server.url = "__DOMAIN__/seafhttp" 78 | file_server.label = "File server" 79 | file_server.allowed = "visitors" 80 | file_server.auth_header = false 81 | file_server.show_tile = false 82 | file_server.protected = true 83 | 84 | notification_server.url = "__DOMAIN__/notification" 85 | notification_server.label = "Notification server" 86 | notification_server.allowed = "visitors" 87 | notification_server.auth_header = false 88 | notification_server.show_tile = false 89 | notification_server.protected = true 90 | 91 | webdav.url = "__DOMAIN__/seafdav" 92 | webdav.label = "Webdav" 93 | webdav.allowed = "visitors" 94 | webdav.auth_header = false 95 | webdav.protected = true 96 | webdav.show_tile = false 97 | 98 | notification.url = "__DOMAIN__/notification" 99 | notification.label = "Client-notification" 100 | notification.allowed = "visitors" 101 | notification.auth_header = false 102 | notification.protected = true 103 | notification.show_tile = false 104 | 105 | media.url = "/media" 106 | media.label = "Media" 107 | media.allowed = "visitors" 108 | media.auth_header = true 109 | media.protected = true 110 | media.show_tile = false 111 | 112 | [resources.ports] 113 | seahub.default = 8000 114 | fileserver.default = 8082 115 | notificationserver.default = 8083 116 | webdav.default = 8080 117 | 118 | [resources.sources.main] 119 | format = "docker" 120 | extract = true 121 | prefetch = false 122 | 123 | amd64.url = "seafileltd/seafile-mc:12.0.11" 124 | amd64.sha256 = "4ab87f4b7fd9a712f614386c3362049d1701161e07e0f88681fdddcc3e543680" 125 | 126 | arm64.url = "seafileltd/seafile-mc:12.0.11" 127 | arm64.sha256 = "4ab87f4b7fd9a712f614386c3362049d1701161e07e0f88681fdddcc3e543680" 128 | 129 | [resources.sources.notification_server] 130 | format = "docker" 131 | extract = true 132 | prefetch = false 133 | 134 | amd64.url = "seafileltd/notification-server:12.0.11" 135 | amd64.sha256 = "3155a6e476109edcb36be9b953e551d0dbe0ec37839b2c64d4f6dc559642532e" 136 | 137 | arm64.url = "seafileltd/notification-server:12.0.11" 138 | arm64.sha256 = "3155a6e476109edcb36be9b953e551d0dbe0ec37839b2c64d4f6dc559642532e" 139 | 140 | [resources.apt] 141 | packages = ["mariadb-server", "memcached"] 142 | 143 | [resources.database] 144 | type = "mysql" 145 | -------------------------------------------------------------------------------- /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..d79523691 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 c6379c728..de892a6d6 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, admin_password, enable_sasl, sasl_mechanism, follow_referrals) 68 | except Exception as e: 69 | @@ -949,15 +952,20 @@ 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, password, enable_sasl, sasl_mechanism, follow_referrals) 75 | - except Exception as e: 76 | - raise Exception(e) 77 | + # BEGIN YNH PATCH 78 | + if not no_check_password: 79 | + try: 80 | + user_bind = self.ldap_bind(server_url, dn, authc_id, password, enable_sasl, sasl_mechanism, follow_referrals) 81 | + except Exception as e: 82 | + raise Exception(e) 83 | 84 | - user_bind.unbind_s() 85 | + user_bind.unbind_s() 86 | + # END YNH PATCH 87 | return nickname, contact_email, user_role 88 | 89 | - def authenticate(self, ldap_user=None, password=None): 90 | + # BEGIN YNH PATCH 91 | + def authenticate(self, ldap_user=None, password=None, no_check_password=False): 92 | + # END YNH PATCH 93 | if not ENABLE_LDAP: 94 | return 95 | 96 | @@ -972,7 +980,9 @@ class CustomLDAPBackend(object): 97 | nickname, contact_email, user_role = self.search_user( 98 | LDAP_SERVER_URL, LDAP_ADMIN_DN, LDAP_ADMIN_PASSWORD, ENABLE_SASL, SASL_MECHANISM, 99 | SASL_AUTHC_ID_ATTR, LDAP_BASE_DN, LDAP_LOGIN_ATTR, login_attr, password, LDAP_FILTER, 100 | - LDAP_CONTACT_EMAIL_ATTR, LDAP_USER_ROLE_ATTR, LDAP_FOLLOW_REFERRALS) 101 | + # BEGIN YNH PATCH 102 | + LDAP_CONTACT_EMAIL_ATTR, LDAP_USER_ROLE_ATTR, LDAP_FOLLOW_REFERRALS, no_check_password) 103 | + # END YNH PATCH 104 | ldap_provider = LDAP_PROVIDER 105 | except Exception as e: 106 | if ENABLE_MULTI_LDAP: 107 | @@ -987,7 +997,9 @@ class CustomLDAPBackend(object): 108 | MULTI_LDAP_1_SERVER_URL, MULTI_LDAP_1_ADMIN_DN, MULTI_LDAP_1_ADMIN_PASSWORD, 109 | MULTI_LDAP_1_ENABLE_SASL, MULTI_LDAP_1_SASL_MECHANISM, MULTI_LDAP_1_SASL_AUTHC_ID_ATTR, 110 | MULTI_LDAP_1_BASE_DN, MULTI_LDAP_1_LOGIN_ATTR, login_attr, password, MULTI_LDAP_1_FILTER, 111 | - MULTI_LDAP_1_CONTACT_EMAIL_ATTR, MULTI_LDAP_1_USER_ROLE_ATTR, MULTI_LDAP_1_FOLLOW_REFERRALS) 112 | + # BEGIN YNH PATCH 113 | + MULTI_LDAP_1_CONTACT_EMAIL_ATTR, MULTI_LDAP_1_USER_ROLE_ATTR, MULTI_LDAP_1_FOLLOW_REFERRALS, no_check_password) 114 | + # END YNH PATCH 115 | ldap_provider = MULTI_LDAP_1_PROVIDER 116 | except Exception as e: 117 | logger.error(e) 118 | -------------------------------------------------------------------------------- /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 seafile_code="$seafile_image/opt/seafile/seafile-server-$seafile_version" 12 | 13 | readonly time_zone="$(timedatectl show --value --property=Timezone)" 14 | readonly python_version="$(python3 -V | cut -d' ' -f2 | cut -d. -f1-2)" 15 | systemd_seafile_bind_mount="$data_dir/seafile-data:/opt/seafile/seafile-data " 16 | systemd_seafile_bind_mount+="$data_dir/seahub-data:/opt/seafile/seahub-data " 17 | systemd_seafile_bind_mount+="/var/log/$app:/opt/seafile/logs " 18 | systemd_seafile_bind_mount+="$install_dir/conf:/opt/seafile/conf " 19 | systemd_seafile_bind_mount+="$install_dir/ccnet:/opt/seafile/ccnet " 20 | systemd_seafile_bind_mount+="/proc " 21 | systemd_seafile_bind_mount+="/dev" 22 | 23 | systemd_notification_server_bind_mount="$data_dir/notification-data:/opt/notification-data " 24 | systemd_notification_server_bind_mount+="/proc " 25 | systemd_notification_server_bind_mount+="/dev" 26 | 27 | # Create special path with / at the end 28 | if [[ "$path" == '/' ]] 29 | then 30 | readonly path2="$path" 31 | else 32 | readonly path2="$path/" 33 | fi 34 | 35 | if [ "${LANG:0:2}" == C. ]; then 36 | readonly language=en 37 | else 38 | readonly language="${LANG:0:2}" 39 | fi 40 | 41 | #================================================= 42 | # DEFINE ALL COMMON FONCTIONS 43 | #================================================= 44 | 45 | run_seafile_cmd() { 46 | ynh_hide_warnings systemd-run --wait --pty --uid="$app" --gid="$app" \ 47 | --property=RootDirectory="$install_dir"/seafile_image \ 48 | --property="BindPaths=$systemd_seafile_bind_mount" \ 49 | --property=EnvironmentFile="$install_dir"/seafile_env.conf \ 50 | "$@" 51 | } 52 | 53 | install_source() { 54 | # set correct seafile version in patch 55 | ynh_replace --match="__SEAFILE_VERSION__" --replace="$seafile_version" --file="$YNH_APP_BASEDIR"/patches/main/import_ldap_user_when_authenticated_from_remoteUserBackend.patch 56 | ynh_setup_source_custom --dest_dir="$seafile_image" --full_replace 57 | mkdir -p "$install_dir"/seafile_image/opt/seafile/{seafile-data,seahub-data,conf,ccnet,logs} 58 | grep "^$app:x" /etc/passwd | sed "s|$install_dir|/opt/seafile|" >> "$install_dir"/seafile_image/etc/passwd 59 | grep "^$app:x" /etc/group >> "$install_dir"/seafile_image/etc/group 60 | grep "^$app:x" /etc/group- >> "$install_dir"/seafile_image/etc/group- 61 | grep "^$app:" /etc/shadow >> "$install_dir"/seafile_image/etc/shadow 62 | 63 | ynh_setup_source_custom --dest_dir="$notification_image" --full_replace --source_id=notification_server 64 | grep "^$app:x" /etc/passwd | sed "s|$install_dir|/opt/seafile|" >> "$install_dir"/seafile_image/etc/passwd 65 | grep "^$app:x" /etc/group >> "$install_dir"/seafile_image/etc/group 66 | grep "^$app:x" /etc/group- >> "$install_dir"/seafile_image/etc/group- 67 | grep "^$app:" /etc/shadow >> "$install_dir"/seafile_image/etc/shadow 68 | } 69 | 70 | set_permission() { 71 | chown "$app:$app" "$install_dir" 72 | chmod u=rwx,g=rx,o= "$install_dir" 73 | chown -R "$app:$app" "$install_dir"/{conf,ccnet} 74 | chmod -R u+rwX,g+rX-w,o= "$install_dir"/{conf,ccnet} 75 | chown -R "$app:$app" "$install_dir"/seafile_image/opt/seafile 76 | chmod -R u+rwX,g-w,o= "$install_dir"/seafile_image/opt/seafile 77 | chown -R "$app:$app" /var/log/"$app" 78 | chmod -R u=rwX,g=rX,o= /var/log/"$app" 79 | 80 | # Allow to www-data to each dir between /opt/yunohost/seafile and /opt/yunohost/seafile/seafile_image/opt/seafile/seahub/media 81 | local dir_path='' 82 | while read -r -d/ dir_name; do 83 | dir_path+="$dir_name/" 84 | if [[ "$dir_path" == "$install_dir"* ]] && [ -e "$dir_path" ]; then 85 | setfacl -m user:www-data:rX "$dir_path" 86 | fi 87 | done <<< "$seafile_code/seahub/media" 88 | test -e "$install_dir/seafile_image/opt/seafile/seahub-data" && setfacl -m user:www-data:rX "$install_dir/seafile_image/opt/seafile/seahub-data" 89 | test -e "$seafile_code/seahub/media" && setfacl -R -m user:www-data:rX "$seafile_code/seahub/media" 90 | 91 | # At install time theses directory are not available 92 | test -e "$install_dir"/seahub-data && setfacl -m user:www-data:rX "$data_dir" 93 | test -e "$install_dir"/seahub-data && setfacl -R -m user:www-data:rX "$data_dir"/seahub-data 94 | 95 | chmod u=rwx,g=rx,o= "$data_dir" 96 | find "$data_dir" \( \! -perm -o= \ 97 | -o \! -user "$app" \ 98 | -o \! -group "$app" \) \ 99 | -exec chown "$app:$app" {} \; \ 100 | -exec chmod o= {} \; 101 | } 102 | 103 | clean_url_in_db_config() { 104 | sql_request='DELETE FROM `constance_config` WHERE `constance_key`= "SERVICE_URL"' 105 | ynh_mysql_db_shell <<< "$sql_request" --database=seahubdb 106 | sql_request='DELETE FROM `constance_config` WHERE `constance_key`= "FILE_SERVER_ROOT"' 107 | ynh_mysql_db_shell <<< "$sql_request" --database=seahubdb 108 | } 109 | 110 | ensure_vars_set() { 111 | ynh_app_setting_set_default --key=jwt_private --value=$(ynh_string_random -l 32) 112 | ynh_app_setting_set_default --key=protect_against_basic_auth_spoofing --value=false 113 | } 114 | -------------------------------------------------------------------------------- /scripts/backup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ../settings/scripts/experimental_helper.sh 9 | source ../settings/scripts/_common.sh 10 | 11 | if systemctl is-active "$app" --quiet || systemctl is-active seahub --quiet; then 12 | 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'" 13 | fi 14 | 15 | #================================================= 16 | # STANDARD BACKUP STEPS 17 | #================================================= 18 | 19 | # # Backup app files 20 | ynh_print_info "Backing up code..." 21 | ynh_backup "$install_dir" 22 | ynh_print_info "Backing up user data..." 23 | ynh_backup "$data_dir" --dest_path="data" 24 | 25 | ynh_print_info "Backing up configuration..." 26 | ynh_backup "/etc/nginx/conf.d/$domain.d/${app}.conf" 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/fail2ban/jail.d/"$app".conf 31 | ynh_backup /etc/fail2ban/filter.d/"$app".conf 32 | 33 | # Backup logs 34 | ynh_backup "/var/log/$app" 35 | 36 | # Backup mysql 37 | ynh_print_info "Backing up database" 38 | ynh_mysql_dump_db > "${YNH_CWD}"/seafiledb.dmp 39 | ynh_mysql_dump_db ccnetdb > "${YNH_CWD}"/ccnetdb.dmp 40 | ynh_mysql_dump_db seahubdb > "${YNH_CWD}"/seahubdb.dmp 41 | 42 | ynh_print_info "Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." 43 | -------------------------------------------------------------------------------- /scripts/change_url: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./experimental_helper.sh 9 | source ./_common.sh 10 | 11 | #================================================= 12 | 13 | ynh_script_progression "Updating NGINX web server configuration..." 14 | ynh_config_change_url_nginx 15 | 16 | #================================================= 17 | # SPECIFIC MODIFICATIONS 18 | #================================================= 19 | 20 | ynh_script_progression "Stoping services..." 21 | 22 | # Stop service before any change 23 | ynh_systemctl --service=seafile --action=stop 24 | ynh_systemctl --service=seahub --action=stop 25 | ynh_systemctl --service="$app"-notification.service --action=stop 26 | sleep 2 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 | ynh_script_progression "Updating seafile configuration..." 33 | 34 | # Update Seafile Config 35 | ynh_config_add --jinja --template=seahub_settings.py --destination="$install_dir"/conf/seahub_settings.py 36 | ynh_config_add --template=seafile.conf --destination="$install_dir"/conf/seafile.conf 37 | ynh_config_add --template=gunicorn.conf.py --destination="$install_dir"/conf/gunicorn.conf.py 38 | ynh_config_add --template=seafdav.conf --destination="$install_dir"/conf/seafdav.conf 39 | ynh_config_add --template=seafevents.conf --destination="$install_dir"/conf/seafevents.conf 40 | ynh_config_add --jinja --template=seafile_env.j2 --destination="$install_dir"/seafile_env.conf 41 | ynh_config_add --jinja --template=notification_server_env.j2 --destination="$install_dir"/notification_server_env.conf 42 | 43 | # Update permissions 44 | ynh_permission_url --permission=file_server --url="$domain"/seafhttp 45 | ynh_permission_url --permission=webdav --url="$domain"/seafdav 46 | 47 | # Clean url in config in DB 48 | clean_url_in_db_config 49 | 50 | # Avoid the current effect 51 | sleep 2 52 | 53 | # Reload services 54 | ynh_script_progression "Starting services..." 55 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 56 | sleep 2 57 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 58 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 59 | 60 | ynh_script_progression "Change of URL completed for $app" --time= 61 | -------------------------------------------------------------------------------- /scripts/experimental_helper.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YunoHost-Apps/seafile_ynh/983b48296194287a00923a98c75abb9e7c4a282b/scripts/experimental_helper.sh -------------------------------------------------------------------------------- /scripts/install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./experimental_helper.sh 9 | source ./_common.sh 10 | source ./ynh_setup_source 11 | 12 | ensure_vars_set 13 | 14 | #================================================= 15 | 16 | ynh_script_progression "Creating base directory..." 17 | 18 | if [ -n "$(ls -A "$data_dir")" ]; then 19 | old_data_dir_path="${data_dir}_$(date '+%Y%m%d.%H%M%S')" 20 | ynh_print_warn "Data directory was not empty. Data was moved to $old_data_dir_path" 21 | mkdir -p "$old_data_dir_path" 22 | mv -t "$old_data_dir_path" "$data_dir"/* 23 | fi 24 | 25 | mkdir -p /var/log/"$app" 26 | mkdir -p "$data_dir"/{seafile-data,seahub-data,notification-data} 27 | mkdir -p "$install_dir"/{conf,ccnet} 28 | 29 | # Download new version from sources 30 | ynh_script_progression "Installing sources files..." 31 | install_source 32 | 33 | # init databases 34 | ynh_script_progression "Configuring MySQL database..." 35 | db_user=seafile 36 | ynh_''mysql_create_db ccnetdb "$db_user" "$db_pwd" 37 | ynh_''mysql_create_db seahubdb "$db_user" "$db_pwd" 38 | 39 | ynh_script_progression "Configuring application..." 40 | 41 | ynh_config_add --jinja --template=seafile_env.j2 --destination="$install_dir"/seafile_env.conf 42 | ynh_config_add --jinja --template=notification_server_env.j2 --destination="$install_dir"/notification_server_env.conf 43 | 44 | # Run install script 45 | set_permission 46 | ynh_replace_regex --match='seafile_config.seafile_dir = seafile_config.validate_seafile_dir(seafile_dir)' \ 47 | --replace='seafile_config.seafile_dir = seafile_dir' \ 48 | --file="$seafile_code/setup-seafile-mysql.py" 49 | ynh_replace_regex --match="Utils.error('Ccnet config dir \\\"%s\\\" already exists.' % ccnet_config.ccnet_dir)" \ 50 | --replace='patched = 1' \ 51 | --file="$seafile_code/setup-seafile-mysql.py" 52 | ynh_replace --match='db_config.root_conn.close()' \ 53 | --replace='patched = 1' \ 54 | --file="$seafile_code/setup-seafile-mysql.py" 55 | run_seafile_cmd bash "/opt/seafile/seafile-server-$seafile_version/setup-seafile-mysql.sh" auto \ 56 | --server-name "$server_name" \ 57 | --server-ip "$domain" \ 58 | --fileserver-port "$port_fileserver" \ 59 | --use-existing-db 1 \ 60 | --mysql-host 127.0.0.1 \ 61 | --mysql-port 3306 \ 62 | --mysql-user "$db_user" \ 63 | --mysql-user-passwd "$db_pwd" \ 64 | -s "$db_name" \ 65 | -c ccnetdb \ 66 | -b seahubdb 67 | 68 | # Retrive values from auto generated config file 69 | seahub_secret_key=$(grep -P 'SECRET_KEY\s*=\s*".+"' "$install_dir"/conf/seahub_settings.py | cut -d'"' -f2) 70 | ynh_app_setting_set --key=seahub_secret_key --value="$seahub_secret_key" 71 | 72 | # Update seafile config files 73 | if [ "$(lsb_release -c -s)" == bullseye ]; then 74 | # Fix header for retro compability on Yunohost 11 75 | ynh_replace --match="'HTTP_YNH_USER_EMAIL'" --replace="'HTTP_EMAIL'" --file="../conf/seahub_settings.py" 76 | fi 77 | ynh_config_add --jinja --template=seahub_settings.py --destination="$install_dir"/conf/seahub_settings.py 78 | ynh_config_add --template=seafile.conf --destination="$install_dir"/conf/seafile.conf 79 | ynh_config_add --template=gunicorn.conf.py --destination="$install_dir"/conf/gunicorn.conf.py 80 | ynh_config_add --template=seafdav.conf --destination="$install_dir"/conf/seafdav.conf 81 | ynh_config_add --template=seafevents.conf --destination="$install_dir"/conf/seafevents.conf 82 | 83 | # Configure admin info 84 | # It will be used the first start 85 | admin_email=$(ynh_user_get_info --username="$admin" --key='mail') 86 | cp ../conf/create_admin.json "$install_dir"/conf/admin.txt 87 | ynh_replace --match=__ADMIN__ --replace="$admin_email" --file="$install_dir"/conf/admin.txt 88 | ynh_replace_regex --match=__PASSWORD__ --replace="$admin_password" --file="$install_dir"/conf/admin.txt 89 | 90 | # Use symlink to store data 91 | if [ -e "$install_dir"/seafile-data ]; then 92 | mv -t "$data_dir"/seafile-data "$install_dir"/seafile-data/* 93 | ynh_safe_rm "$install_dir"/seafile-data 94 | fi 95 | if [ -e "$install_dir"/seahub-data ]; then 96 | mv -t "$data_dir"/seahub-data "$install_dir"/seahub-data/* 97 | ynh_safe_rm "$install_dir"/seahub-data 98 | fi 99 | if [ -e "$install_dir"/logs ]; then 100 | mv -t /var/log/"$app" "$install_dir"/logs/* 101 | ynh_safe_rm "$install_dir"/logs 102 | fi 103 | ln -s "$data_dir"/seafile-data "$install_dir"/seafile-data 104 | ln -s "$data_dir"/seahub-data "$install_dir"/seahub-data 105 | ln -s /var/log/"$app" "$install_dir"/logs 106 | 107 | # Fix local warning 108 | ynh_replace --match=en_US.UTF-8 --replace="${LANG:-'en_US.UTF-8'}" --file="$seafile_code/seahub.sh" 109 | 110 | # Add Seafile Server to startup 111 | ynh_script_progression "Configuring $app's systemd service..." 112 | ynh_config_add_systemd --service=seafile --template="$app".service 113 | ynh_config_add_systemd --service=seahub --template=seahub.service 114 | ynh_config_add_systemd --service=seafile-notification --template="$app"-notification.service 115 | 116 | # register yunohost service 117 | yunohost service add "$app" --description 'Main service for seafile server.' 118 | yunohost service add seahub --description 'Seafile server web interface.' 119 | yunohost service add "$app"-notification --description 'Seafile client notification server.' 120 | 121 | # Config nginx 122 | ynh_script_progression "Configuring nginx..." 123 | ynh_config_add_nginx 124 | 125 | # Add logrotate 126 | ynh_script_progression "Configuring log rotation..." 127 | ynh_config_add_logrotate /var/log/"$app" 128 | 129 | # Add fail2ban 130 | ynh_script_progression "Configuring fail2ban..." 131 | ynh_config_add_fail2ban --logpath="$install_dir"/logs/seahub.log 132 | 133 | #================================================= 134 | 135 | # Set all permissions 136 | ynh_script_progression "Protecting directory..." 137 | set_permission 138 | 139 | # Start service 140 | sleep 3 141 | 142 | ynh_script_progression "Starting seafile services..." 143 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 144 | sleep 2 145 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 146 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 147 | 148 | ynh_script_progression "Installation of $app completed" 149 | -------------------------------------------------------------------------------- /scripts/remove: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./experimental_helper.sh 9 | source ./_common.sh 10 | 11 | #================================================= 12 | # STANDARD REMOVE 13 | #================================================= 14 | 15 | ynh_script_progression "Stoping services..." 16 | 17 | # Stop all services 18 | ynh_systemctl --service="$app" --action=stop 19 | ynh_systemctl --service=seahub --action=stop 20 | ynh_systemctl --service="$app"-notification.service --action=stop 21 | 22 | # Force to kill all process in case of a process is not stoped cleanly 23 | pkill -f seafile-controller || true 24 | pkill -f seaf-server || true 25 | pkill -f ccnet-server || true 26 | pkill -f seahub || true 27 | 28 | # Remove databases 29 | ynh_script_progression "Removing databases..." 30 | ynh_''mysql_drop_db ccnetdb 31 | ynh_''mysql_drop_db seahubdb 32 | 33 | # Remove systemd service 34 | ynh_script_progression "Removing systemd units..." 35 | ynh_config_remove_systemd seafile 36 | ynh_config_remove_systemd seahub 37 | 38 | # Remove nginx config 39 | ynh_script_progression "Removing nginx configuration..." 40 | ynh_config_remove_nginx 41 | 42 | # Remove logrotate 43 | ynh_config_remove_logrotate 44 | 45 | # Remove the dedicated fail2ban config 46 | ynh_script_progression "Removing fail2ban configuration..." 47 | ynh_config_remove_fail2ban 48 | 49 | ynh_script_progression "Removing seafile service..." 50 | yunohost service remove seafile 51 | yunohost service remove seahub 52 | 53 | ynh_script_progression "Removal of $app completed" 54 | 55 | sleep 1 56 | -------------------------------------------------------------------------------- /scripts/restore: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ../settings/scripts/experimental_helper.sh 9 | source ../settings/scripts/_common.sh 10 | 11 | ynh_script_progression "Loading settings..." 12 | 13 | #================================================= 14 | # STANDARD RESTORATION STEPS 15 | #================================================= 16 | 17 | # Restore all config and data 18 | ynh_script_progression "Restoring files..." 19 | ynh_restore_everything 20 | # Restore mysql dump 21 | ynh_script_progression "Restoring database..." 22 | ynh_''mysql_create_db ccnetdb "$db_user" "$db_pwd" 23 | ynh_''mysql_create_db seahubdb "$db_user" "$db_pwd" 24 | su -c "mysql -u ${app} -p$db_pwd $db_name < ${YNH_CWD}/seafiledb.dmp" 25 | su -c "mysql -u ${app} -p$db_pwd ccnetdb < ${YNH_CWD}/ccnetdb.dmp" 26 | su -c "mysql -u ${app} -p$db_pwd seahubdb < ${YNH_CWD}/seahubdb.dmp" 27 | 28 | #================================================= 29 | 30 | # Add logrotate 31 | ynh_script_progression "Configuring log rotation..." 32 | mkdir -p /var/log/"$app" 33 | ynh_config_add_logrotate /var/log/"$app" 34 | 35 | # Set all permissions 36 | ynh_script_progression "Protecting directory..." 37 | set_permission 38 | 39 | # Enable service and start seafile 40 | ynh_script_progression "Reconfiguring application..." 41 | systemctl daemon-reload 42 | systemctl enable "$app" --quiet 43 | systemctl enable seahub --quiet 44 | systemctl enable "$app"-notification --quiet 45 | 46 | # Add Seafile to YunoHost's monitored services 47 | ynh_script_progression "Register seafile service..." 48 | yunohost service add "$app" --description 'Main service for seafile server.' 49 | yunohost service add seahub --description 'Seafile server web interface.' 50 | yunohost service add "$app"-notification --description 'Seafile client notification server.' 51 | 52 | ynh_script_progression "Reloading services..." 53 | 54 | # Reload nginx 55 | systemctl reload nginx.service 56 | 57 | # Reload fail2ban 58 | ynh_systemctl --service=fail2ban --action=reload 59 | 60 | # Avoid the current effect 61 | sleep 5 62 | 63 | # Restart service 64 | ynh_script_progression "Starting seafile services..." 65 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 66 | sleep 2 67 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 68 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 69 | 70 | ynh_script_progression "Restoration completed for $app" 71 | -------------------------------------------------------------------------------- /scripts/upgrade: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #================================================= 4 | # GENERIC START 5 | #================================================= 6 | 7 | # Import common cmd 8 | source ./experimental_helper.sh 9 | source ./_common.sh 10 | source ./ynh_setup_source 11 | 12 | installed_version="${YNH_APP_CURRENT_VERSION/~ynh*/}" 13 | 14 | ensure_vars_set 15 | 16 | if [ "$YNH_APP_CURRENT_VERSION" == '-' ] || ynh_app_upgrading_from_version_before_or_equal_to '7.0~ynh1'; then 17 | ynh_die "Upgrade from this version not supported" 18 | fi 19 | 20 | ynh_script_progression "Stoping services..." 21 | 22 | ynh_systemctl --service="$app" --action=stop 23 | ynh_systemctl --service=seahub --action=stop 24 | ynh_systemctl --service="$app"-notification.service --action=stop 25 | sleep 5 26 | pkill -f seafile-controller || true 27 | pkill -f seaf-server || true 28 | pkill -f ccnet-server || true 29 | pkill -f seahub || true 30 | 31 | # Migrate DB name if needed 32 | if mysqlshow | grep -q seafiledb; then 33 | mysqlconn="mysql -u root" 34 | sql_mv_params=$($mysqlconn -N -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES \ 35 | WHERE table_schema='seafiledb'") 36 | for name in $sql_mv_params; do 37 | $mysqlconn -e "RENAME TABLE seafiledb.$name to $db_name.$name"; 38 | done; 39 | $mysqlconn -e "DROP DATABASE seafiledb" 40 | ynh_replace --match='db_name = seafiledb' --replace='db_name = seafile' --file="$install_dir"/conf/seafile.conf 41 | sed -i "s|password\s*=\s*.*^|password = $db_pwd|g" "$install_dir"/conf/seafile.conf 42 | fi 43 | 44 | # Set missing settings 45 | 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)" 46 | 47 | # 48 | # Update data dir if needed 49 | # 50 | 51 | # Create link to /home/yunohost.app/seafile/seafile-data in case of old install with data dir defined in config instead of symlink 52 | # Also update link if not pointing to correct path 53 | if [ ! -L /home/yunohost.app/seafile-data ] || \ 54 | [ "$(readlink "$install_dir"/seafile-data)" != "$data_dir/seafile-data" ]; then 55 | mv "$install_dir"/seafile-data "$install_dir/seafile-data_$(date '+%Y%m%d.%H%M%S')" 56 | ln -s "$data_dir"/seafile-data "$install_dir"/seafile-data 57 | fi 58 | 59 | # Move if needed old /home/yunohost.app/seafile-data dir to /home/yunohost.app/seafile/seafile-data 60 | if [ -e /home/yunohost.app/seafile-data ]; then 61 | if [ -e "$data_dir" ]; then 62 | mv "$data_dir" "${data_dir}_$(date '+%Y%m%d.%H%M%S')" 63 | fi 64 | mkdir -p "$data_dir" 65 | mv /home/yunohost.app/seafile-data "$data_dir"/ 66 | fi 67 | 68 | # In case of seafile-data content was directly stored in /home/yunohost.app/seafile 69 | if [ -e "$data_dir"/storage ]; then 70 | mkdir -p "$data_dir"/seafile-data 71 | 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 72 | fi 73 | 74 | # Move seahub data to /home/yunohost.app/seafile/seahub-data 75 | if [ ! -L "$install_dir"/seahub-data ]; then 76 | if [ -e "$data_dir"/seahub-data ]; then 77 | mv "$data_dir"/seahub-data "$data_dir/seahub-data_$(date '+%Y%m%d.%H%M%S')" 78 | fi 79 | mv "$install_dir"/seahub-data "$data_dir"/ 80 | ln -s "$data_dir"/seahub-data "$install_dir"/seahub-data 81 | fi 82 | 83 | # Move logs storage to /var/log/seafile 84 | if [ ! -L "$install_dir"/logs ]; then 85 | if [ -e /var/log/"$app" ]; then 86 | mv /var/log/"$app" /var/log/"${app}_$(date '+%Y%m%d.%H%M%S')" 87 | fi 88 | mv "$install_dir"/logs /var/log/"${app}" 89 | ln -s /var/log/"${app}" "$install_dir"/logs 90 | fi 91 | 92 | # Ensure all data dir are created 93 | mkdir -p /var/log/"$app" 94 | mkdir -p "$data_dir"/{seafile-data,seahub-data,notification-data} 95 | 96 | ynh_script_progression "Upgrading source files..." 97 | 98 | # Download new version from sources 99 | ynh_script_progression "Installing sources files..." 100 | if [ "$YNH_APP_UPGRADE_TYPE" == UPGRADE_APP ]; then 101 | install_source 102 | fi 103 | 104 | ynh_script_progression "Configuring application..." 105 | 106 | # permission to execute update script and expect helper 107 | set_permission 108 | 109 | ynh_config_add --jinja --template=seafile_env.j2 --destination="$install_dir"/seafile_env.conf 110 | ynh_config_add --jinja --template=notification_server_env.j2 --destination="$install_dir"/notification_server_env.conf 111 | 112 | # do the upgrade ( the ";&" syntax mean when it go in the first case which is true it do all the next case) 113 | case "$installed_version" in 114 | "4."* ) 115 | # Update seafile by script 116 | ynh_die "Upgrade form the version 4.x was removed. Upgrade from this version won't be supported any more." 117 | ;& 118 | "5."* ) 119 | # Update seafile by script 120 | ynh_die "Upgrade form the version 5.x was removed. Upgrade from this version won't be supported any more." 121 | ;& 122 | "6."* ) 123 | ynh_die "Upgrade form the version 6.x was removed. Upgrade from this version won't be supported any more." 124 | ;& 125 | "7.0"* ) 126 | # Fix file comment 127 | 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 128 | 129 | # Update seafile by script 130 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_7.0_7.1.sh" 131 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_7.0_7.1.sh" 132 | 133 | # Fix seafile data link. Look like that the upgrade script of seafile don't always work correctly 134 | if [ -e "$install_dir"/seafile-data ]; then 135 | old_data_dir_path="$install_dir/seafile-data$(date '+%Y%m%d.%H%M%S')" 136 | mv "$install_dir/seafile-data" "$old_data_dir_path" 137 | fi 138 | ln -s "$data_dir" "$install_dir"/seafile-data 139 | ;& 140 | "7.1."* ) 141 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_7.1_8.0.sh" 142 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_7.1_8.0.sh" 143 | ;& 144 | "8."* ) 145 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_8.0_9.0.sh" 146 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_8.0_9.0.sh" 147 | ;& 148 | "9."* ) 149 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_9.0_10.0.sh" 150 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_9.0_10.0.sh" 151 | ;& 152 | "10."* ) 153 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_10.0_11.0.sh" 154 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_10.0_11.0.sh" 155 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/seahub.sh" python-env python3 "/opt/seafile/seafile-server-$seafile_version/migrate_ldapusers.py" 156 | ;& 157 | "11."* ) 158 | ynh_safe_rm "$install_dir"/conf/ccnet.conf 159 | 160 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/upgrade_11.0_12.0.sh" 161 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/upgrade_11.0_12.0.sh" 162 | ;& 163 | esac 164 | 165 | ynh_replace --match='read dummy' --replace='# patched' --file="$seafile_code/upgrade/minor-upgrade.sh" 166 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version/upgrade/minor-upgrade.sh" 167 | 168 | # Clean expired sessions, cf: https://manual.seafile.com/12.0/administration/clean_database/ 169 | run_seafile_cmd "/opt/seafile/seafile-server-$seafile_version//seahub.sh" python-env python3 seahub/manage.py clearsessions 170 | 171 | # Clean url in config in DB 172 | clean_url_in_db_config 173 | 174 | # Update seafile config files 175 | if [ "$(lsb_release -c -s)" == bullseye ]; then 176 | # Fix header for retro compability on Yunohost 11 177 | ynh_replace --match="'HTTP_YNH_USER_EMAIL'" --replace="'HTTP_EMAIL'" --file="../conf/seahub_settings.py" 178 | fi 179 | ynh_config_add --jinja --template=seahub_settings.py --destination="$install_dir"/conf/seahub_settings.py 180 | ynh_config_add --template=seafile.conf --destination="$install_dir"/conf/seafile.conf 181 | ynh_config_add --template=gunicorn.conf.py --destination="$install_dir"/conf/gunicorn.conf.py 182 | ynh_config_add --template=seafdav.conf --destination="$install_dir"/conf/seafdav.conf 183 | ynh_config_add --template=seafevents.conf --destination="$install_dir"/conf/seafevents.conf 184 | 185 | # Fix local warning 186 | ynh_replace --match=en_US.UTF-8 --replace="${LANG:-'en_US.UTF-8'}" --file="$seafile_code/seahub.sh" 187 | 188 | #================================================= 189 | 190 | # Config nginx 191 | ynh_config_add_nginx 'seahub_port fileserver_port webdav_port' 192 | 193 | # Add Seafile Server to startup 194 | ynh_script_progression "Updating systemd units..." 195 | ynh_config_add_systemd --service=seafile --template="$app".service 196 | ynh_config_add_systemd --service=seahub --template=seahub.service 197 | ynh_config_add_systemd --service=seafile-notification --template="$app"-notification.service 198 | 199 | #================================================= 200 | 201 | # Set all permissions 202 | ynh_script_progression "Protecting directory..." 203 | set_permission 204 | 205 | # Add logrotate 206 | ynh_script_progression "Configuring log rotation..." 207 | ynh_config_add_logrotate /var/log/"$app" 208 | 209 | # Add fail2ban 210 | ynh_script_progression "Configuring fail2ban..." 211 | ynh_config_add_fail2ban --logpath="$install_dir"/logs/seahub.log 212 | 213 | # register yunohost service 214 | ynh_script_progression "Register seafile service..." 215 | yunohost service add "$app" --description 'Main service for seafile server.' 216 | yunohost service add seahub --description 'Seafile server web interface.' 217 | yunohost service add "$app"-notification --description 'Seafile client notification server.' 218 | 219 | # delete seafile cache 220 | 221 | # restart seafile server 222 | ynh_script_progression "Starting seafile services..." 223 | ynh_systemctl --service=memcached.service -p "systemd" 224 | sleep 5 225 | ynh_systemctl --service="$app" --wait_until='Seafile server started' --log_path=systemd 226 | sleep 2 227 | ynh_systemctl --service=seahub --wait_until='Seahub is started' --log_path=systemd 228 | ynh_systemctl --service="$app"-notification.service --wait_until="notification server started" --log_path=systemd 229 | 230 | # remove old version files 231 | ynh_script_progression "Cleaning system and updating settings..." 232 | for f in "$install_dir"/seafile-server-*;do 233 | if [[ ! "$f" =~ ${seafile_version//./\\.}|latest ]]; then 234 | ynh_safe_rm "$f" 235 | fi 236 | done 237 | 238 | ynh_script_progression "Upgrade of $app completed" 239 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.c11c24b.name = "Version 8.x (Old_version_for_CI_5 branch)" 24 | test_upgrade_from.7a4d00a.name = "Version 9.x" 25 | test_upgrade_from.ef7eb6f.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 | --------------------------------------------------------------------------------