mirror of
https://git.unistra.fr/aius/root/ldap-overleaf-sl.git
synced 2025-05-04 11:45:26 +02:00
Short test with Sharelatex 2.6.1 - seems to work. Use LDAP escape - thx to @SF2311.
This commit is contained in:
parent
831b810e81
commit
90e7681c35
5 changed files with 176 additions and 37 deletions
24
README.md
24
README.md
|
@ -56,8 +56,8 @@ MYDATA=/data
|
||||||
- sharelatex: all projects, tmp files, user files templates and ...
|
- sharelatex: all projects, tmp files, user files templates and ...
|
||||||
- letsencrypt: https certificates
|
- letsencrypt: https certificates
|
||||||
|
|
||||||
*MYDOMAIN* is the FQDN for sharelatex and traefik (letsencrypt) <br/>
|
*MYDOMAIN* is the FQDN for sharelatex and traefik (letsencrypt) or certbot <br/>
|
||||||
*MYDOMAIN*:8443 Traefik Dashboard - Login uses traefik/user.htpasswd : user:admin pass:adminPass change this (e.g. generate a password with htpasswd)
|
*MYDOMAIN*:8443 Traefik Dashboard (docker-compose-traefik.yml) - Login uses traefik/user.htpasswd : user:admin pass:adminPass change this (e.g. generate a password with htpasswd)
|
||||||
*MYMAIL* is the admin mailaddress
|
*MYMAIL* is the admin mailaddress
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -70,7 +70,9 @@ COLLAB_TEXT=Direct share with collaborators is enabled only for activated users!
|
||||||
|
|
||||||
### LDAP Configuration
|
### LDAP Configuration
|
||||||
|
|
||||||
Edit [docker-compose.yml](docker-compose.yml) to fit your local setup.
|
Edit [docker-compose.treafik.yml](docker-compose.traefik.yml) or [docker-compose.treafik.yml](docker-compose.certbot.yml) to fit your local setup.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
LDAP_SERVER: ldaps://LDAPSERVER:636
|
LDAP_SERVER: ldaps://LDAPSERVER:636
|
||||||
|
@ -132,9 +134,23 @@ docker network create web
|
||||||
```
|
```
|
||||||
to create a network for the docker instances.
|
to create a network for the docker instances.
|
||||||
|
|
||||||
|
|
||||||
|
## Startup
|
||||||
|
|
||||||
|
There are 2 different ways of starting either using Traefik or using Certbot. Adapt the one you want to use.
|
||||||
|
|
||||||
|
### Using Traefik
|
||||||
|
|
||||||
Then start docker containers (with loadbalancer):
|
Then start docker containers (with loadbalancer):
|
||||||
```
|
```
|
||||||
export NUMINSTANCES=1
|
export NUMINSTANCES=1
|
||||||
docker-compose up -d --scale sharelatex=$NUMINSTANCES
|
docker-compose -f docker-compose.traefik.yml up -d --scale sharelatex=$NUMINSTANCES
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Certbot
|
||||||
|
Enable line 65/66 and 69/70 in ldapoverleaf-sl/Dockerfile and ``make`` again.
|
||||||
|
|
||||||
|
```
|
||||||
|
docker-compose -f docker-compose.certbot.yml up -d --scale sharelatex=$NUMINSTANCES
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
142
docker-compose.certbot.yml
Normal file
142
docker-compose.certbot.yml
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
version: '2.2'
|
||||||
|
services:
|
||||||
|
sharelatex:
|
||||||
|
restart: always
|
||||||
|
image: ldap-overleaf-sl
|
||||||
|
container_name: ldap-overleaf-sl
|
||||||
|
depends_on:
|
||||||
|
mongo:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
simple-certbot:
|
||||||
|
condition: service_started
|
||||||
|
privileged: false
|
||||||
|
ports:
|
||||||
|
- 443:443
|
||||||
|
links:
|
||||||
|
- mongo
|
||||||
|
- redis
|
||||||
|
- simple-certbot
|
||||||
|
volumes:
|
||||||
|
- ${MYDATA}/sharelatex:/var/lib/sharelatex
|
||||||
|
- ${MYDATA}/letsencrypt:/etc/letsencrypt
|
||||||
|
- ${MYDATA}/letsencrypt/live/${MYDOMAIN}/:/etc/letsencrypt/certs/domain
|
||||||
|
environment:
|
||||||
|
SHARELATEX_APP_NAME: Overleaf
|
||||||
|
SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex
|
||||||
|
SHARELATEX_SITE_URL: https://${MYDOMAIN}
|
||||||
|
SHARELATEX_NAV_TITLE: Overleaf - run by ${MYDOMAIN}
|
||||||
|
#SHARELATEX_HEADER_IMAGE_URL: https://${MYDOMAIN}/logo.svg
|
||||||
|
SHARELATEX_ADMIN_EMAIL: ${MYMAIL}
|
||||||
|
SHARELATEX_LEFT_FOOTER: '[{"text": "Powered by <a href=\"https://www.sharelatex.com\">ShareLaTeX</a> 2016"} ]'
|
||||||
|
SHARELATEX_RIGHT_FOOTER: '[{"text": "LDAP Overleaf (beta)"} ]'
|
||||||
|
SHARELATEX_EMAIL_FROM_ADDRESS: "noreply@${MYDOMAIN}"
|
||||||
|
# SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID:
|
||||||
|
# SHARELATEX_EMAIL_AWS_SES_SECRET_KEY:
|
||||||
|
SHARELATEX_EMAIL_SMTP_HOST: smtp.${MYDOMAIN}
|
||||||
|
SHARELATEX_EMAIL_SMTP_PORT: 587
|
||||||
|
SHARELATEX_EMAIL_SMTP_SECURE: 'false'
|
||||||
|
# SHARELATEX_EMAIL_SMTP_USER:
|
||||||
|
# SHARELATEX_EMAIL_SMTP_PASS:
|
||||||
|
# SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: true
|
||||||
|
# SHARELATEX_EMAIL_SMTP_IGNORE_TLS: false
|
||||||
|
SHARELATEX_CUSTOM_EMAIL_FOOTER: "This system is run by ${MYDOMAIN} - please contact ${MYMAIL} if you experience any issues."
|
||||||
|
|
||||||
|
# make public links accessible w/o login (link sharing issue)
|
||||||
|
# https://github.com/overleaf/docker-image/issues/66
|
||||||
|
# https://github.com/overleaf/overleaf/issues/628
|
||||||
|
# https://github.com/overleaf/web/issues/367
|
||||||
|
# Fixed in 2.0.2 (Release date: 2019-11-26)
|
||||||
|
SHARELATEX_ALLOW_PUBLIC_ACCESS: 'true'
|
||||||
|
SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING: 'true'
|
||||||
|
|
||||||
|
SHARELATEX_SECURE_COOKIE: 'true'
|
||||||
|
SHARELATEX_BEHIND_PROXY: 'true'
|
||||||
|
|
||||||
|
LDAP_SERVER: ldaps://LDAPSERVER:636
|
||||||
|
LDAP_SERVER: ldaps://LDAPSERVER:636
|
||||||
|
LDAP_BASE: ou=people,dc=DOMAIN,dc=TLD
|
||||||
|
LDAP_BINDDN: ou=someunit,ou=people,dc=DOMAIN,dc=TLS
|
||||||
|
# By default tries to bind directly with the ldap user - this user has to be in the LDAP GROUP
|
||||||
|
LDAP_GROUP_FILTER: '(memberof=cn=GROUPNAME,ou=groups,dc=DOMAIN,dc=TLD)'
|
||||||
|
|
||||||
|
# If user is in ADMIN_GROUP on user creation (first login) isAdmin is set to true.
|
||||||
|
# Admin Users can invite external (non ldap) users. This feature makes only sense
|
||||||
|
# when ALLOW_EMAIL_LOGIN is set to 'true'. Additionally adminsy can send
|
||||||
|
# system wide messages.
|
||||||
|
#LDAP_ADMIN_GROUP_FILTER: '(memberof=cn=ADMINGROUPNAME,ou=groups,dc=DOMAIN,dc=TLD)'
|
||||||
|
ALLOW_EMAIL_LOGIN: 'false'
|
||||||
|
|
||||||
|
# All users in the LDAP_GROUP_FILTER are loaded from the ldap server into contacts.
|
||||||
|
# This LDAP search happens without bind. If you want this and your LDAP needs a bind you can
|
||||||
|
# adapt this in the function getLdapContacts() in ContactsController.js (lines 82 - 107)
|
||||||
|
LDAP_CONTACTS: 'false'
|
||||||
|
|
||||||
|
# Same property, unfortunately with different names in
|
||||||
|
# different locations
|
||||||
|
SHARELATEX_REDIS_HOST: redis
|
||||||
|
REDIS_HOST: redis
|
||||||
|
REDIS_PORT: 6379
|
||||||
|
|
||||||
|
ENABLED_LINKED_FILE_TYPES: 'url,project_file'
|
||||||
|
|
||||||
|
# Enables Thumbnail generation using ImageMagick
|
||||||
|
ENABLE_CONVERSIONS: 'true'
|
||||||
|
|
||||||
|
mongo:
|
||||||
|
restart: always
|
||||||
|
image: mongo
|
||||||
|
container_name: mongo
|
||||||
|
ports:
|
||||||
|
- 27017
|
||||||
|
volumes:
|
||||||
|
- ${MYDATA}/mongo_data:/data/db
|
||||||
|
healthcheck:
|
||||||
|
test: echo 'db.stats().ok' | mongo localhost:27017/test --quiet
|
||||||
|
interval: 10s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
redis:
|
||||||
|
restart: always
|
||||||
|
image: redis:5.0.0
|
||||||
|
container_name: redis
|
||||||
|
# modify to get rid of the redis issue #35 and #19 with a better solution
|
||||||
|
# WARNING: /proc/sys/net/core/somaxconn is set to the lower value of 128.
|
||||||
|
# for vm overcommit: enable first on host system
|
||||||
|
# sysctl vm.overcommit_memory=1 (and add it to rc.local)
|
||||||
|
# then you do not need it in the redis container
|
||||||
|
sysctls:
|
||||||
|
- net.core.somaxconn=65535
|
||||||
|
# - vm.overcommit_memory=1
|
||||||
|
ports:
|
||||||
|
- 6379
|
||||||
|
volumes:
|
||||||
|
- ${MYDATA}/redis_data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
|
||||||
|
simple-certbot:
|
||||||
|
restart: always
|
||||||
|
image: certbot/certbot
|
||||||
|
container_name: simple-certbot
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
volumes:
|
||||||
|
- ${MYDATA}/letsencrypt:/etc/letsencrypt
|
||||||
|
# a bit hacky but this docker image uses very little disk-space
|
||||||
|
# best practices for ssl and nginx are set in the ldap-overleaf-sl Dockerfile
|
||||||
|
entrypoint:
|
||||||
|
- "/bin/sh"
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
trap exit TERM;\
|
||||||
|
certbot certonly --standalone -d ${MYDOMAIN} --agree-tos -m ${MYMAIL} -n ; \
|
||||||
|
while :; do certbot renew; sleep 240h & wait $${!}; done;
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,6 @@ services:
|
||||||
links:
|
links:
|
||||||
- mongo
|
- mongo
|
||||||
- redis
|
- redis
|
||||||
#- simple-certbot
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${MYDATA}/sharelatex:/var/lib/sharelatex
|
- ${MYDATA}/sharelatex:/var/lib/sharelatex
|
||||||
- ${MYDATA}/letsencrypt:/etc/letsencrypt:ro
|
- ${MYDATA}/letsencrypt:/etc/letsencrypt:ro
|
||||||
|
@ -211,26 +210,6 @@ services:
|
||||||
networks:
|
networks:
|
||||||
- web
|
- web
|
||||||
|
|
||||||
|
|
||||||
# simple-certbot:
|
|
||||||
# restart: always
|
|
||||||
# image: certbot/certbot
|
|
||||||
# container_name: simple-certbot
|
|
||||||
# ports:
|
|
||||||
# - 80:80
|
|
||||||
# volumes:
|
|
||||||
# - ${MYDATA}/letsencrypt:/etc/letsencrypt
|
|
||||||
# # a bit hacky but this docker image uses very little disk-space
|
|
||||||
# # best practices for ssl and nginx are set in the ldap-overleaf-sl Dockerfile
|
|
||||||
# entrypoint:
|
|
||||||
# - "/bin/sh"
|
|
||||||
# - -c
|
|
||||||
# - |
|
|
||||||
# trap exit TERM;\
|
|
||||||
# certbot certonly --standalone -d ${MYDOMAIN} --agree-tos -m ${MYMAIL} -n ; \
|
|
||||||
# while :; do certbot renew; sleep 240h & wait $${!}; done;
|
|
||||||
#
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
web:
|
web:
|
||||||
external: true
|
external: true
|
|
@ -16,6 +16,7 @@ WORKDIR /var/www/sharelatex/web
|
||||||
RUN npm install -g npm
|
RUN npm install -g npm
|
||||||
# clean cache (might solve issue #2)
|
# clean cache (might solve issue #2)
|
||||||
#RUN npm cache clean --force
|
#RUN npm cache clean --force
|
||||||
|
RUN npm install ldap-escape
|
||||||
RUN npm install ldapts-search
|
RUN npm install ldapts-search
|
||||||
RUN npm install ldapts
|
RUN npm install ldapts
|
||||||
#RUN npm install bcrypt@5.0.0
|
#RUN npm install bcrypt@5.0.0
|
||||||
|
@ -44,16 +45,16 @@ RUN sed -iE "s%placeholder=.*$%placeholder=\"${collab_text}\"%g" /var/www/sharel
|
||||||
RUN sed -iE "s%-synctex=1\",%-synctex=1\", \"-shell-escape\",%g" /var/www/sharelatex/clsi/app/js/LatexRunner.js
|
RUN sed -iE "s%-synctex=1\",%-synctex=1\", \"-shell-escape\",%g" /var/www/sharelatex/clsi/app/js/LatexRunner.js
|
||||||
|
|
||||||
# Too much changes to do inline (>10 Lines).
|
# Too much changes to do inline (>10 Lines).
|
||||||
#COPY sharelatex/settings.pug /var/www/sharelatex/web/app/views/user/
|
COPY sharelatex/settings.pug /var/www/sharelatex/web/app/views/user/
|
||||||
#COPY sharelatex/navbar.pug /var/www/sharelatex/web/app/views/layout/
|
COPY sharelatex/navbar.pug /var/www/sharelatex/web/app/views/layout/
|
||||||
|
|
||||||
# Non LDAP User Registration for Admins
|
# Non LDAP User Registration for Admins
|
||||||
#COPY sharelatex/admin-index.pug /var/www/sharelatex/web/app/views/admin/index.pug
|
COPY sharelatex/admin-index.pug /var/www/sharelatex/web/app/views/admin/index.pug
|
||||||
#RUN rm /var/www/sharelatex/web/app/views/admin/register.pug
|
RUN rm /var/www/sharelatex/web/app/views/admin/register.pug
|
||||||
|
|
||||||
### To remove comments entirly (bug https://github.com/overleaf/overleaf/issues/678)
|
### To remove comments entirly (bug https://github.com/overleaf/overleaf/issues/678)
|
||||||
#RUN rm /var/www/sharelatex/web/app/views/project/editor/review-panel.pug
|
RUN rm /var/www/sharelatex/web/app/views/project/editor/review-panel.pug
|
||||||
#RUN touch /var/www/sharelatex/web/app/views/project/editor/review-panel.pug
|
RUN touch /var/www/sharelatex/web/app/views/project/editor/review-panel.pug
|
||||||
|
|
||||||
### Nginx and Certificates
|
### Nginx and Certificates
|
||||||
# enable https via letsencrypt
|
# enable https via letsencrypt
|
||||||
|
|
|
@ -10,6 +10,7 @@ const {
|
||||||
const util = require('util')
|
const util = require('util')
|
||||||
|
|
||||||
const { Client } = require('ldapts');
|
const { Client } = require('ldapts');
|
||||||
|
const ldapEscape = require('ldap-escape');
|
||||||
|
|
||||||
// https://www.npmjs.com/package/@overleaf/o-error
|
// https://www.npmjs.com/package/@overleaf/o-error
|
||||||
// have a look if we can do nice error messages.
|
// have a look if we can do nice error messages.
|
||||||
|
@ -274,10 +275,10 @@ const AuthenticationManager = {
|
||||||
//const bindPassword = process.env.LDAP_BIND_PW
|
//const bindPassword = process.env.LDAP_BIND_PW
|
||||||
const ldap_bd = process.env.LDAP_BINDDN
|
const ldap_bd = process.env.LDAP_BINDDN
|
||||||
const ldap_base = process.env.LDAP_BASE
|
const ldap_base = process.env.LDAP_BASE
|
||||||
const uid = query.email.split('@')[0]
|
var mail = query.email
|
||||||
const filterstr = '(&' + process.env.LDAP_GROUP_FILTER + '(uid=' + uid + '))'
|
var uid = query.email.split('@')[0]
|
||||||
const userDn = 'uid=' + uid + ',' + ldap_bd;
|
const filterstr = '(&' + process.env.LDAP_GROUP_FILTER + '(' + ldapEscape.filter`uid=${uid}` + '))'
|
||||||
var mail = ""
|
const userDn = ldapEscape.filter`uid=${uid}` + ',' + ldap_bd;
|
||||||
var firstname = ""
|
var firstname = ""
|
||||||
var lastname = ""
|
var lastname = ""
|
||||||
var isAdmin = false
|
var isAdmin = false
|
||||||
|
@ -311,8 +312,8 @@ const AuthenticationManager = {
|
||||||
try {
|
try {
|
||||||
// if admin filter is set - only set admin for user in ldap group
|
// if admin filter is set - only set admin for user in ldap group
|
||||||
// does not matter - admin is deactivated: managed through ldap
|
// does not matter - admin is deactivated: managed through ldap
|
||||||
if (process.env.LDAP_ADMIN_GROUP_FILTER) {
|
if (process.env.LDAP_ADMIN_GROUP_FILTER) {
|
||||||
const adminfilter = '(&' + process.env.LDAP_ADMIN_GROUP_FILTER + '(uid=' + uid + '))'
|
const adminfilter = '(&' + process.env.LDAP_ADMIN_GROUP_FILTER + '(' +ldapEscape.filter`uid=${uid}` + '))'
|
||||||
adminEntry = await client.search(ldap_base, {
|
adminEntry = await client.search(ldap_base, {
|
||||||
scope: 'sub',
|
scope: 'sub',
|
||||||
filter: adminfilter,
|
filter: adminfilter,
|
||||||
|
|
Loading…
Add table
Reference in a new issue