1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 18:47:23 +00:00

Merge remote-tracking branch 'proxy_login/1105-reverse-proxy-login'

Fix for creation of bool config settings (before: new bool columns where always created with true as default)
This commit is contained in:
Ozzieisaacs 2020-01-05 13:37:02 +01:00
commit 6a07cfba65
5 changed files with 72 additions and 16 deletions

View File

@ -350,6 +350,10 @@ def _configuration_update_helper():
_config_int("config_updatechannel") _config_int("config_updatechannel")
# Reverse proxy login configuration
_config_checkbox("config_allow_reverse_proxy_header_login")
_config_string("config_reverse_proxy_login_header_name")
# GitHub OAuth configuration # GitHub OAuth configuration
if config.config_login_type == constants.LOGIN_OAUTH: if config.config_login_type == constants.LOGIN_OAUTH:
active_oauths = 0 active_oauths = 0

View File

@ -106,6 +106,9 @@ class _Settings(_Base):
config_updatechannel = Column(Integer, default=constants.UPDATE_STABLE) config_updatechannel = Column(Integer, default=constants.UPDATE_STABLE)
config_reverse_proxy_login_header_name = Column(String)
config_allow_reverse_proxy_header_login = Column(Boolean, default=False)
def __repr__(self): def __repr__(self):
return self.__class__.__name__ return self.__class__.__name__
@ -250,8 +253,7 @@ class _ConfigSQL(object):
for k, v in self.__dict__.items(): for k, v in self.__dict__.items():
if k[0] == '_': if k[0] == '_':
continue continue
if hasattr(s, k): # and getattr(s, k, None) != v: if hasattr(s, k):
# log.debug("_Settings save '%s' = %r", k, v)
setattr(s, k, v) setattr(s, k, v)
log.debug("_ConfigSQL updating storage") log.debug("_ConfigSQL updating storage")
@ -279,7 +281,13 @@ def _migrate_table(session, orm_class):
if sys.version_info < (3, 0): if sys.version_info < (3, 0):
if isinstance(column.default.arg,unicode): if isinstance(column.default.arg,unicode):
column.default.arg = column.default.arg.encode('utf-8') column.default.arg = column.default.arg.encode('utf-8')
column_default = "" if column.default is None else ("DEFAULT %r" % column.default.arg) if column.default is None:
column_default = ""
else:
if isinstance(column.default.arg, bool):
column_default = ("DEFAULT %r" % int(column.default.arg))
else:
column_default = ("DEFAULT %r" % column.default.arg)
alter_table = "ALTER TABLE %s ADD COLUMN `%s` %s %s" % (orm_class.__tablename__, alter_table = "ALTER TABLE %s ADD COLUMN `%s` %s %s" % (orm_class.__tablename__,
column_name, column_name,
column.type, column.type,

View File

@ -1,4 +1,7 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% macro display_bool_setting(setting_value) -%}
{% if setting_value %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}
{%- endmacro %}
{% block body %} {% block body %}
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
@ -23,11 +26,11 @@
<td>{{user.email}}</td> <td>{{user.email}}</td>
<td>{{user.kindle_mail}}</td> <td>{{user.kindle_mail}}</td>
<td>{{user.downloads.count()}}</td> <td>{{user.downloads.count()}}</td>
<td class="hidden-xs">{% if user.role_admin() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> <td class="hidden-xs">{{ display_bool_setting(user.role_admin()) }}</td>
<td class="hidden-xs">{% if user.role_download() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> <td class="hidden-xs">{{ display_bool_setting(user.role_download()) }}</td>
<td class="hidden-xs">{% if user.role_viewer() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> <td class="hidden-xs">{{ display_bool_setting(user.role_viewer()) }}</td>
<td class="hidden-xs">{% if user.role_upload() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> <td class="hidden-xs">{{ display_bool_setting(user.role_upload()) }}</td>
<td class="hidden-xs">{% if user.role_edit() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> <td class="hidden-xs">{{ display_bool_setting(user.role_edit()) }}</td>
</tr> </tr>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
@ -83,20 +86,30 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-7">{{_('Uploading')}}</div> <div class="col-xs-6 col-sm-7">{{_('Uploading')}}</div>
<div class="col-xs-6 col-sm-5">{% if config.config_uploading %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</div> <div class="col-xs-6 col-sm-5">{{ display_bool_setting(config.config_uploading) }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-7">{{_('Anonymous browsing')}}</div> <div class="col-xs-6 col-sm-7">{{_('Anonymous browsing')}}</div>
<div class="col-xs-6 col-sm-5">{% if config.config_anonbrowse %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</div> <div class="col-xs-6 col-sm-5">{{ display_bool_setting(config.config_anonbrowse) }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-7">{{_('Public registration')}}</div> <div class="col-xs-6 col-sm-7">{{_('Public registration')}}</div>
<div class="col-xs-6 col-sm-5">{% if config.config_public_reg %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</div> <div class="col-xs-6 col-sm-5">{{ display_bool_setting(config.config_public_reg) }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-7">{{_('Remote login')}}</div> <div class="col-xs-6 col-sm-7">{{_('Remote login')}}</div>
<div class="col-xs-6 col-sm-5">{% if config.config_remote_login %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</div> <div class="col-xs-6 col-sm-5">{{ display_bool_setting(config.config_remote_login) }}</div>
</div> </div>
<div class="row">
<div class="col-xs-6 col-sm-7">{{_('Reverse proxy login')}}</div>
<div class="col-xs-6 col-sm-5">{{ display_bool_setting(config.config_allow_reverse_proxy_header_login) }}</div>
</div>
{% if config.config_allow_reverse_proxy_header_login %}
<div class="row">
<div class="col-xs-6 col-sm-7">{{_('Reverse proxy header name')}}</div>
<div class="col-xs-6 col-sm-5">{{ config.config_reverse_proxy_login_header_name }}</div>
</div>
{% endif %}
</div> </div>
<div class="btn btn-default"><a id="basic_config" href="{{url_for('admin.configuration')}}">{{_('Basic Configuration')}}</a></div> <div class="btn btn-default"><a id="basic_config" href="{{url_for('admin.configuration')}}">{{_('Basic Configuration')}}</a></div>
<div class="btn btn-default"><a id="view_config" href="{{url_for('admin.view_configuration')}}">{{_('UI Configuration')}}</a></div> <div class="btn btn-default"><a id="view_config" href="{{url_for('admin.view_configuration')}}">{{_('UI Configuration')}}</a></div>

View File

@ -200,7 +200,7 @@
</select> </select>
</div> </div>
{% if feature_support['ldap'] %} {% if feature_support['ldap'] %}
<div data-related="login-settings-1"> <div data-related="login-settings-1">
<div class="form-group"> <div class="form-group">
<label for="config_ldap_provider_url">{{_('LDAP Server Host Name or IP Address')}}</label> <label for="config_ldap_provider_url">{{_('LDAP Server Host Name or IP Address')}}</label>
<input type="text" class="form-control" id="config_ldap_provider_url" name="config_ldap_provider_url" value="{% if config.config_ldap_provider_url != None %}{{ config.config_ldap_provider_url }}{% endif %}" autocomplete="off"> <input type="text" class="form-control" id="config_ldap_provider_url" name="config_ldap_provider_url" value="{% if config.config_ldap_provider_url != None %}{{ config.config_ldap_provider_url }}{% endif %}" autocomplete="off">
@ -271,6 +271,16 @@
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
<div class="form-group">
<input type="checkbox" id="config_allow_reverse_proxy_header_login" name="config_allow_reverse_proxy_header_login" data-control="reverse-proxy-login-settings" {% if config.config_allow_reverse_proxy_header_login %}checked{% endif %}>
<label for="config_allow_reverse_proxy_header_login">{{_('Allow Reverse Proxy Authentication')}}</label>
</div>
<div data-related="reverse-proxy-login-settings">
<div class="form-group">
<label for="config_reverse_proxy_login_header_name">{{_('Reverse Proxy Header Name')}}</label>
<input type="text" class="form-control" id="config_reverse_proxy_login_header_name" name="config_reverse_proxy_login_header_name" value="{% if config.config_reverse_proxy_login_header_name != None %}{{ config.config_reverse_proxy_login_header_name }}{% endif %}" autocomplete="off">
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -114,14 +114,35 @@ web = Blueprint('web', __name__)
log = logger.create() log = logger.create()
# ################################### Login logic and rights management ############################################### # ################################### Login logic and rights management ###############################################
def _fetch_user_by_name(username):
return ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == username.lower()).first()
@lm.user_loader @lm.user_loader
def load_user(user_id): def load_user(user_id):
return ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() return ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first()
@lm.header_loader @lm.request_loader
def load_user_from_header(header_val): def load_user_from_request(request):
auth_header = request.headers.get("Authorization")
if auth_header:
user = load_user_from_auth_header(auth_header)
if user:
return user
if config.config_allow_reverse_proxy_header_login:
rp_header_name = config.config_reverse_proxy_login_header_name
if rp_header_name:
rp_header_username = request.headers.get(rp_header_name)
if rp_header_username:
user = _fetch_user_by_name(rp_header_username)
if user:
return user
return
def load_user_from_auth_header(header_val):
if header_val.startswith('Basic '): if header_val.startswith('Basic '):
header_val = header_val.replace('Basic ', '', 1) header_val = header_val.replace('Basic ', '', 1)
basic_username = basic_password = '' basic_username = basic_password = ''
@ -131,7 +152,7 @@ def load_user_from_header(header_val):
basic_password = header_val.split(':')[1] basic_password = header_val.split(':')[1]
except TypeError: except TypeError:
pass pass
user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == basic_username.lower()).first() user = _fetch_user_by_name(basic_username)
if user and check_password_hash(str(user.password), basic_password): if user and check_password_hash(str(user.password), basic_password):
return user return user
return return