diff --git a/README.md b/README.md
index 1cc2eb8..dc4f95a 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,8 @@ or
chmod o+rw path/to/library
```
* Do not use a Nextcloud folder. It's all right if the folder is an external storage in Nextcloud but not if it's an internal one : Changing the data in the library will cause trouble with the sync
+* "Magic link feature is not yet available
+
## Links
* Report a bug: https://github.com/YunoHost-Apps/calibre_ynh/issues
@@ -68,6 +70,8 @@ sudo yunohost app upgrade calibreweb -u https://github.com/Yunohost-Apps/calibre
- [ ] User and possibly LDAP integration
- [X] Package_check integration
- [X] On backup/remove/upgrade : check for database location to update settings
+- [ ] enable magic link
+- [ ] Add cronjob to reload database
## LICENSE
diff --git a/conf/app.src b/conf/app.src
index c765e11..33e5909 100644
--- a/conf/app.src
+++ b/conf/app.src
@@ -1,4 +1,3 @@
-#useless as long as V1.0 not issued
-SOURCE_URL=https://github.com/janeczku/calibre-web/archive/d0fd1a46014006138977398ee65f48c98df937e7.zip
-SOURCE_SUM=0d297719f32670840fb1fcee52d3e73fa6213127709809d9a232f862d037af03
+SOURCE_URL=https://github.com/janeczku/calibre-web/archive/c527d1f49a2213e523957fd90d814c075bacde89.zip
+SOURCE_SUM=61aff733df259382ae53646e5445ac973a0c4fe70e54ec4d3ed63a7f66c4f04f
SOURCE_FORMAT=zip
diff --git a/conf/init_calibre_db_settings b/conf/init_calibre_db_settings
index 8dacf91..f600faa 100644
--- a/conf/init_calibre_db_settings
+++ b/conf/init_calibre_db_settings
@@ -8,4 +8,7 @@ config_use_goodreads=0,
config_logfile=\'\',
config_converterpath=\'\',
config_calibre=\'\',
-config_uploading=\'$upload\'
\ No newline at end of file
+config_use_ldap=1,
+config_ldap_provider_url=\'localhost:389\',
+config_ldap_dn=\'uid=%s,ou=users,dc=yunohost,dc=org\',
+config_uploading=\'$upload\'
diff --git a/conf/nginx.conf b/conf/nginx.conf
index 75e244a..64bc976 100644
--- a/conf/nginx.conf
+++ b/conf/nginx.conf
@@ -4,12 +4,13 @@ location __PATH__ {
if ($scheme = http) {
rewrite ^ https://$server_name$request_uri? permanent;
}
- proxy_pass http://localhost:__PORT__;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header Host $http_host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Scheme $scheme;
- proxy_set_header X-Script-Name __PATH__;
+ proxy_pass http://localhost:__PORT__;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header Host $http_host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Scheme $scheme;
+ proxy_set_header X-Script-Name __PATH__;
+ proxy_set_header X-Remote-User $remote_user;
# Include SSOWAT user panel.
include conf.d/yunohost_panel.conf.inc;
diff --git a/scripts/install b/scripts/install
index e552210..a2e1473 100755
--- a/scripts/install
+++ b/scripts/install
@@ -92,7 +92,7 @@ pip install --target $final_path/vendor -r $final_path/requirements.txt
#=================================================
#Cannot use empty string for X-script-name, causes an issue in the python prg
if [ $path_url = "/" ] ; then
- ynh_replace_string "X-Script-Name __PATH__;" "X-Script-Name /$app;" ../conf/nginx.conf
+ ynh_replace_string "X-Script-Name __PATH__;" "X-Script-Name $app;" ../conf/nginx.conf
fi
# Create a dedicated nginx config
diff --git a/sources/patches/app-config.patch b/sources/patches/app-config.patch
new file mode 100644
index 0000000..c816372
--- /dev/null
+++ b/sources/patches/app-config.patch
@@ -0,0 +1,24 @@
+--- a/cps/templates/config_edit.html 2019-01-12 09:01:08.000000000 +0100
++++ b/cps/templates/config_edit.html 2019-01-13 11:21:11.000000000 +0100
+@@ -162,6 +162,21 @@
+
+
+ {% endif %}
++
++
++
++
++
++
+
+
+
diff --git a/sources/patches/app-ub.patch b/sources/patches/app-ub.patch
new file mode 100644
index 0000000..5da0e64
--- /dev/null
+++ b/sources/patches/app-ub.patch
@@ -0,0 +1,72 @@
+--- a/cps/ub.py 2019-01-12 09:01:08.000000000 +0100
++++ b/cps/ub.py 2019-01-13 11:21:11.000000000 +0100
+@@ -148,6 +148,14 @@
+ def __repr__(self):
+ return '' % self.nickname
+
++ #Login via LDAP method
++ @staticmethod
++ def try_login(username, password):
++ conn = get_ldap_connection()
++ conn.simple_bind_s(
++ config.config_ldap_dn.replace("%s", username),
++ password
++ )
+
+ # Baseclass for Users in Calibre-Web, settings which are depending on certain users are stored here. It is derived from
+ # User Base (all access methods are declared there)
+@@ -306,6 +314,9 @@
+ config_use_goodreads = Column(Boolean)
+ config_goodreads_api_key = Column(String)
+ config_goodreads_api_secret = Column(String)
++ config_use_ldap = Column(Boolean)
++ config_ldap_provider_url = Column(String)
++ config_ldap_dn = Column(String)
+ config_mature_content_tags = Column(String)
+ config_logfile = Column(String)
+ config_ebookconverter = Column(Integer, default=0)
+@@ -379,6 +390,9 @@
+ self.config_use_goodreads = data.config_use_goodreads
+ self.config_goodreads_api_key = data.config_goodreads_api_key
+ self.config_goodreads_api_secret = data.config_goodreads_api_secret
++ self.config_use_ldap = data.config_use_ldap
++ self.config_ldap_provider_url = data.config_ldap_provider_url
++ self.config_ldap_dn = data.config_ldap_dn
+ if data.config_mature_content_tags:
+ self.config_mature_content_tags = data.config_mature_content_tags
+ else:
+@@ -662,13 +676,20 @@
+ conn.execute("ALTER TABLE Settings ADD column `config_calibre` String DEFAULT ''")
+ session.commit()
+ try:
++ session.query(exists().where(Settings.config_use_ldap)).scalar()
++ except exc.OperationalError:
++ conn = engine.connect()
++ conn.execute("ALTER TABLE Settings ADD column `config_use_ldap` INTEGER DEFAULT 0")
++ conn.execute("ALTER TABLE Settings ADD column `config_ldap_provider_url` String DEFAULT ''")
++ conn.execute("ALTER TABLE Settings ADD column `config_ldap_dn` String DEFAULT ''")
++ session.commit()
++ try:
+ session.query(exists().where(Settings.config_theme)).scalar()
+ except exc.OperationalError: # Database is not compatible, some rows are missing
+ conn = engine.connect()
+ conn.execute("ALTER TABLE Settings ADD column `config_theme` INTEGER DEFAULT 0")
+ session.commit()
+
+-
+ # Remove login capability of user Guest
+ conn = engine.connect()
+ conn.execute("UPDATE user SET password='' where nickname = 'Guest' and password !=''")
+@@ -778,6 +799,12 @@
+ migrate_Database()
+ clean_database()
+
++#get LDAP connection
++def get_ldap_connection():
++ import ldap
++ conn = ldap.initialize('ldap://{}'.format(config.config_ldap_provider_url))
++ return conn
++
+ # Generate global Settings Object accessible from every file
+ config = Config()
+ searched_ids = {}
diff --git a/sources/patches/app-web.patch b/sources/patches/app-web.patch
new file mode 100644
index 0000000..1145a8d
--- /dev/null
+++ b/sources/patches/app-web.patch
@@ -0,0 +1,73 @@
+--- ./ori-calibre-web/cps/web.py 2019-01-12 09:01:08.000000000 +0100
++++ ./calibre-web-Yunohost_integration/cps/web.py 2019-01-13 20:11:57.000000000 +0100
+@@ -58,6 +58,8 @@
+ import server
+ from reverseproxy import ReverseProxied
+
++vlogout = 0
++
+ try:
+ from googleapiclient.errors import HttpError
+ except ImportError:
+@@ -2360,10 +2362,29 @@
+ return redirect(url_for('basic_configuration'))
+ if current_user is not None and current_user.is_authenticated:
+ return redirect(url_for('index'))
++ auth_user = request.headers.get('X-Remote-User')
++ global vlogout
++ if auth_user and config.config_use_ldap and not vlogout:
++ vlogout = 0
++ user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == auth_user.strip().lower()).first()
++ login_user(user, remember=True)
++ flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success")
++ return redirect(url_for("index"))
+ if request.method == "POST":
+ form = request.form.to_dict()
+ user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == form['username'].strip().lower()).first()
+- if user and check_password_hash(user.password, form['password']) and user.nickname is not "Guest":
++ if config.config_use_ldap and user:
++ import ldap
++ try:
++ ub.User.try_login(form['username'], form['password'])
++ login_user(user, remember=True)
++ flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success")
++ return redirect_back(url_for("index"))
++ except ldap.INVALID_CREDENTIALS:
++ ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr)
++ app.logger.info('LDAP Login failed for user "' + form['username'] + '" IP-adress: ' + ipAdress)
++ flash(_(u"Wrong Username or Password"), category="error")
++ elif user and check_password_hash(user.password, form['password']) and user.nickname is not "Guest":
+ login_user(user, remember=True)
+ flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success")
+ return redirect_back(url_for("index"))
+@@ -2384,6 +2405,8 @@
+ @login_required
+ def logout():
+ if current_user is not None and current_user.is_authenticated:
++ global vlogout
++ vlogout = 1
+ logout_user()
+ return redirect(url_for('login'))
+
+@@ -3088,6 +3111,21 @@
+ if "config_ebookconverter" in to_save:
+ content.config_ebookconverter = int(to_save["config_ebookconverter"])
+
++ #LDAP configuratop,
++ if "config_use_ldap" in to_save and to_save["config_use_ldap"] == "on":
++ if not "config_ldap_provider_url" in to_save or not "config_ldap_dn" in to_save:
++ ub.session.commit()
++ flash(_(u'Please enter a LDAP provider and a DN'), category="error")
++ return render_title_template("config_edit.html", content=config, origin=origin,
++ gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError,
++ goodreads=goodreads_support, title=_(u"Basic Configuration"),
++ page="config")
++ else:
++ content.config_use_ldap = 1
++ content.config_ldap_provider_url = to_save["config_ldap_provider_url"]
++ content.config_ldap_dn = to_save["config_ldap_dn"]
++ db_change = True
++
+ # Remote login configuration
+ content.config_remote_login = ("config_remote_login" in to_save and to_save["config_remote_login"] == "on")
+ if not content.config_remote_login: