Fix for #768 (If email server is configured, admins can send user passwords, also domains can be denied from registration)

This commit is contained in:
Ozzieisaacs 2019-12-29 13:54:52 +01:00
parent 01381488f4
commit 5887f0fe6b
7 changed files with 209 additions and 233 deletions

View File

@ -190,10 +190,10 @@ def update_view_configuration():
return view_configuration()
@admi.route("/ajax/editdomain", methods=['POST'])
@admi.route("/ajax/editdomain/<int:allow>", methods=['POST'])
@login_required
@admin_required
def edit_domain():
def edit_domain(allow):
# POST /post
# name: 'username', //name of field (column in db)
# pk: 1 //primary key (record id)
@ -206,14 +206,14 @@ def edit_domain():
return ""
@admi.route("/ajax/adddomain", methods=['POST'])
@admi.route("/ajax/adddomain/<int:allow>", methods=['POST'])
@login_required
@admin_required
def add_domain():
def add_domain(allow):
domain_name = request.form.to_dict()['domainname'].replace('*', '%').replace('?', '_').lower()
check = ub.session.query(ub.Registration).filter(ub.Registration.domain == domain_name).first()
check = ub.session.query(ub.Registration).filter(ub.Registration.domain == domain_name).filter(ub.Registration.allow == allow).first()
if not check:
new_domain = ub.Registration(domain=domain_name)
new_domain = ub.Registration(domain=domain_name, allow=allow)
ub.session.add(new_domain)
ub.session.commit()
return ""
@ -227,18 +227,18 @@ def delete_domain():
ub.session.query(ub.Registration).filter(ub.Registration.id == domain_id).delete()
ub.session.commit()
# If last domain was deleted, add all domains by default
if not ub.session.query(ub.Registration).count():
new_domain = ub.Registration(domain="%.%")
if not ub.session.query(ub.Registration).filter(ub.Registration.allow==1).count():
new_domain = ub.Registration(domain="%.%",allow=1)
ub.session.add(new_domain)
ub.session.commit()
return ""
@admi.route("/ajax/domainlist")
@admi.route("/ajax/domainlist/<int:allow>")
@login_required
@admin_required
def list_domain():
answer = ub.session.query(ub.Registration).all()
def list_domain(allow):
answer = ub.session.query(ub.Registration).filter(ub.Registration.allow == allow).all()
json_dumps = json.dumps([{"domain": r.domain.replace('%', '*').replace('_', '?'), "id": r.id} for r in answer])
js = json.dumps(json_dumps.replace('"', "'")).lstrip('"').strip('"')
response = make_response(js.replace("'", '"'))
@ -605,6 +605,7 @@ def edit_user(user_id):
else:
flash(_(u"Found an existing account for this e-mail address."), category="error")
return render_title_template("user_edit.html", translations=translations, languages=languages,
mail_configured = config.get_mail_server_configured(),
new_user=0, content=content, downloads=downloads, registered_oauth=oauth_check,
title=_(u"Edit User %(nick)s", nick=content.nickname), page="edituser")
if "nickname" in to_save and to_save["nickname"] != content.nickname:
@ -616,11 +617,11 @@ def edit_user(user_id):
return render_title_template("user_edit.html",
translations=translations,
languages=languages,
mail_configured=config.get_mail_server_configured(),
new_user=0, content=content,
downloads=downloads,
registered_oauth=oauth_check,
title=_(u"Edit User %(nick)s",
nick=content.nickname),
title=_(u"Edit User %(nick)s", nick=content.nickname),
page="edituser")
if "kindle_mail" in to_save and to_save["kindle_mail"] != content.kindle_mail:
@ -633,6 +634,7 @@ def edit_user(user_id):
flash(_(u"An unknown error occured."), category="error")
return render_title_template("user_edit.html", translations=translations, languages=languages, new_user=0,
content=content, downloads=downloads, registered_oauth=oauth_check,
mail_configured=config.get_mail_server_configured(),
title=_(u"Edit User %(nick)s", nick=content.nickname), page="edituser")

View File

@ -701,9 +701,13 @@ def speaking_language(languages=None):
# from https://code.luasoftware.com/tutorials/flask/execute-raw-sql-in-flask-sqlalchemy/
def check_valid_domain(domain_text):
domain_text = domain_text.split('@', 1)[-1].lower()
sql = "SELECT * FROM registration WHERE :domain LIKE domain;"
sql = "SELECT * FROM registration WHERE (:domain LIKE domain and allow = 1);"
result = ub.session.query(ub.Registration).from_statement(text(sql)).params(domain=domain_text).all()
return len(result)
if not len(result):
return False
sql = "SELECT * FROM registration WHERE (:domain LIKE domain and allow = 0);"
result = ub.session.query(ub.Registration).from_statement(text(sql)).params(domain=domain_text).all()
return not len(result)
# Orders all Authors in the list according to authors sort

View File

@ -19,21 +19,41 @@
$(function() {
$("#domain_submit").click(function(event) {
$("#domain_allow_submit").click(function(event) {
event.preventDefault();
$("#domain_add").ajaxForm();
$("#domain_add_allow").ajaxForm();
$(this).closest("form").submit();
$.ajax ({
method:"get",
url: window.location.pathname + "/../../ajax/domainlist",
url: window.location.pathname + "/../../ajax/domainlist/1",
async: true,
timeout: 900,
success:function(data) {
$("#domain-table").bootstrapTable("load", data);
$("#domain-allow-table").bootstrapTable("load", data);
}
});
});
$("#domain-table").bootstrapTable({
$("#domain-allow-table").bootstrapTable({
formatNoMatches: function () {
return "";
},
striped: false
});
$("#domain_deny_submit").click(function(event) {
event.preventDefault();
$("#domain_add_deny").ajaxForm();
$(this).closest("form").submit();
$.ajax ({
method:"get",
url: window.location.pathname + "/../../ajax/domainlist/0",
async: true,
timeout: 900,
success:function(data) {
$("#domain-deny-table").bootstrapTable("load", data);
}
});
});
$("#domain-deny-table").bootstrapTable({
formatNoMatches: function () {
return "";
},
@ -50,14 +70,22 @@ $(function() {
$("#DeleteDomain").modal("hide");
$.ajax({
method:"get",
url: window.location.pathname + "/../../ajax/domainlist",
url: window.location.pathname + "/../../ajax/domainlist/1",
async: true,
timeout: 900,
success:function(data) {
$("#domain-table").bootstrapTable("load", data);
$("#domain-allow-table").bootstrapTable("load", data);
}
});
$.ajax({
method:"get",
url: window.location.pathname + "/../../ajax/domainlist/0",
async: true,
timeout: 900,
success:function(data) {
$("#domain-deny-table").bootstrapTable("load", data);
}
});
});
//triggered when modal is about to be shown
$("#DeleteDomain").on("show.bs.modal", function(e) {

View File

@ -41,22 +41,40 @@
</form>
{% if g.allow_registration %}
<h2>{{_('Allowed domains for registering')}}</h2>
<table class="table table-no-bordered" id="domain-table" data-url="{{url_for('admin.list_domain')}}" data-id-field="id" data-show-header="false" data-editable-mode="inline">
<form id="domain_add_allow" action="{{ url_for('admin.add_domain',allow=1)}}" method="POST">
<div class="form-group required">
<label for="domainname_allow">{{_('Add Domain')}}</label>
<input type="text" class="form-control" name="domainname" id="domainname_allow" >
</div>
<button id="domain_allow_submit" class="btn btn-default">{{_('Add')}}</button>
</form>
<table class="table table-no-bordered" id="domain-allow-table" data-url="{{url_for('admin.list_domain', allow=1)}}" data-id-field="id" data-show-header="false" data-editable-mode="inline">
<thead>
<tr>
<th data-field="domain" id="domain-allow" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain', allow = 1)}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th>
<th data-field="id" id="id-allow" data-visible="false"></th>
<th data-align="right" data-formatter="TableActions"></th>
</tr>
</thead>
</table>
<h2>{{_('Denied domains for registering')}}</h2>
<table class="table table-no-bordered" id="domain-deny-table" data-url="{{url_for('admin.list_domain', allow=0)}}" data-id-field="id" data-show-header="false" data-editable-mode="inline">
<thead>
<tr>
<th data-field="domain" id="domain" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain')}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th>
<th data-field="id" id="id" data-visible="false"></th>
<th data-field="domain" id="domain-deny" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain', allow = 0)}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th>
<th data-field="id" id="id-deny" data-visible="false"></th>
<th data-align="right" data-formatter="TableActions"></th>
</tr>
</thead>
</table>
<form id="domain_add" action="{{ url_for('admin.add_domain')}}" method="POST">
<form id="domain_add_deny" action="{{ url_for('admin.add_domain',allow=0)}}" method="POST">
<div class="form-group required">
<label for="domainname">{{_('Add Domain')}}</label>
<input type="text" class="form-control" name="domainname" id="domainname" >
<label for="domainname_deny">{{_('Add Domain')}}</label>
<input type="text" class="form-control" name="domainname" id="domainname_deny" >
</div>
<button id="domain_submit" class="btn btn-default">{{_('Add')}}</button>
<button id="domain_deny_submit" class="btn btn-default">{{_('Add')}}</button>
</form>
{% endif %}
</div>
{% endblock %}

View File

@ -14,15 +14,14 @@
<input type="email" class="form-control" name="email" id="email" value="{{ content.email if content.email != None }}" autocomplete="off">
</div>
{% if ( g.user and g.user.role_passwd() or g.user.role_admin() ) and not content.role_anonymous() %}
{% if g.user and g.user.role_admin() and g.allow_registration and not new_user and not profile %}
{% if g.user and g.user.role_admin() and not new_user and not profile and ( mail_configured and content.email if content.email != None %}
<div class="btn btn-default" id="resend_password"><a href="{{url_for('admin.reset_user_password', user_id = content.id) }}">{{_('Reset user Password')}}</a></div>
{% else %}
{% endif %}
<div class="form-group">
<label for="password">{{_('Password')}}</label>
<input type="password" class="form-control" name="password" id="password" value="" autocomplete="off">
</div>
{% endif %}
{% endif %}
<div class="form-group">
<label for="kindle_mail">{{_('Kindle E-Mail')}}</label>
<input type="email" class="form-control" name="kindle_mail" id="kindle_mail" value="{{ content.kindle_mail if content.kindle_mail != None }}">

View File

@ -297,6 +297,7 @@ class Registration(Base):
id = Column(Integer, primary_key=True)
domain = Column(String)
allow = Column(Integer)
def __repr__(self):
return u"<Registration('{0}')>".format(self.domain)
@ -332,24 +333,32 @@ def migrate_Database(session):
if not engine.dialect.has_table(engine.connect(), "registration"):
ReadBook.__table__.create(bind=engine)
conn = engine.connect()
conn.execute("insert into registration (domain) values('%.%')")
conn.execute("insert into registration (domain, allow) values('%.%',1)")
session.commit()
try:
session.query(exists().where(Registration.allow)).scalar()
session.commit()
except exc.OperationalError: # Database is not compatible, some columns are missing
conn = engine.connect()
conn.execute("ALTER TABLE registration ADD column 'allow' INTEGER")
conn.execute("update registration set 'allow' = 1")
session.commit()
# Handle table exists, but no content
cnt = session.query(Registration).count()
if not cnt:
conn = engine.connect()
conn.execute("insert into registration (domain) values('%.%')")
conn.execute("insert into registration (domain, allow) values('%.%',1)")
session.commit()
try:
session.query(exists().where(BookShelf.order)).scalar()
except exc.OperationalError: # Database is not compatible, some rows are missing
except exc.OperationalError: # Database is not compatible, some columns are missing
conn = engine.connect()
conn.execute("ALTER TABLE book_shelf_link ADD column 'order' INTEGER DEFAULT 1")
session.commit()
try:
create = False
session.query(exists().where(User.sidebar_view)).scalar()
except exc.OperationalError: # Database is not compatible, some rows are missing
except exc.OperationalError: # Database is not compatible, some columns are missing
conn = engine.connect()
conn.execute("ALTER TABLE user ADD column `sidebar_view` Integer DEFAULT 1")
session.commit()

View File

@ -30,15 +30,15 @@
<div id='header_parameters' class='row text-center report-parameters'>
<div class="col-xs-6 col-md-4">
<p class='text-justify attribute'><strong>Start Time:</strong> 2019-12-28 15:05:02.169394</p>
<p class='text-justify attribute'><strong>Start Time:</strong> 2019-12-29 09:32:57.266265</p>
</div>
<div class="col-xs-6 col-md-4">
<p class='text-justify attribute'><strong>Stop Time:</strong> 2019-12-28 15:36:05.637251</p>
<p class='text-justify attribute'><strong>Stop Time:</strong> 2019-12-29 10:08:09.098085</p>
</div>
<div class="col-xs-6 col-md-4">
<p class='text-justify attribute'><strong>Duration:</strong> 0:31:03.467857</p>
<p class='text-justify attribute'><strong>Duration:</strong> 0:35:11.831820</p>
</div>
</div>
@ -230,11 +230,11 @@
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr class='failClass'>
<tr class='passClass'>
<td>test_ebook_convert.test_ebook_convert</td>
<td class="text-center">11</td>
<td class="text-center">10</td>
<td class="text-center">1</td>
<td class="text-center">11</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">
@ -276,15 +276,15 @@
</div>
<div class="text-left pull-left">
<pre class="text-left">pt3.4: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 35724)
Receiving message from: ('127.0.0.1', 44766)
Message addressed from: name@host.com
Message addressed to: a5@b.com
Message length : 1
Message length : 42
User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 35726)
Receiving message from: ('127.0.0.1', 44768)
Message addressed from: name@host.com
Message addressed to: a1@b.com
Message length : 2
Message length : 16679
User: name@host.com, Password: 1234</pre>
</div>
<div class="clearfix"></div>
@ -309,10 +309,10 @@ User: name@host.com, Password: 1234</pre>
</div>
<div class="text-left pull-left">
<pre class="text-left">pt3.5: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 35730)
Receiving message from: ('127.0.0.1', 44772)
Message addressed from: name@host.com
Message addressed to: a5@b.com
Message length : 1
Message length : 42
User: name@host.com, Password: 1234</pre>
</div>
<div class="clearfix"></div>
@ -355,45 +355,42 @@ User: name@host.com, Password: 1234</pre>
</div>
<div class="text-left pull-left">
<pre class="text-left">pt3.9: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 35734)
Receiving message from: ('127.0.0.1', 44776)
Message addressed from: name@host.com
Message addressed to: a1@b.com
Message length : 2</pre>
Message length : 22311</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='ft3.10' class='none bg-danger'>
<tr id='pt3.10' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_email_only</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft3.10')">FAIL</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_pt3.10')">PASS</a>
</div>
<!--css div popup start-->
<div id='div_ft3.10' class="popup_window test_output" style="display:none;">
<div id='div_pt3.10' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_ft3.10').style.display='none'"><span
onclick="document.getElementById('div_pt3.10').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">ft3.10: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 35736)
<pre class="text-left">pt3.10: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 44778)
Message addressed from: name@host.com
Message addressed to: a5@b.com
Message length : 1
Message length : 42
User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 35738)
Receiving message from: ('127.0.0.1', 44780)
Message addressed from: name@host.com
Message addressed to: a1@b.com
Message length : 2Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_ebook_convert.py", line 397, in test_email_only
self.assertGreaterEqual(self.email_server.handler.message_size,24256)
AssertionError: 2 not greater than or equal to 24256</pre>
Message length : 17477</pre>
</div>
<div class="clearfix"></div>
</div>
@ -1287,10 +1284,10 @@ AssertionError: 2 not greater than or equal to 24256</pre>
</div>
<div class="text-left pull-left">
<pre class="text-left">pt6.1: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 41832)
Receiving message from: ('127.0.0.1', 47328)
Message addressed from: name@host.com
Message addressed to: a1@b.com
Message length : 2</pre>
Message length : 22013</pre>
</div>
<div class="clearfix"></div>
</div>
@ -1303,121 +1300,111 @@ Message length : 2</pre>
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr class='failClass'>
<tr class='skipClass'>
<td>test_email_ssl.test_SSL</td>
<td class="text-center">4</td>
<td class="text-center">0</td>
<td class="text-center">4</td>
<td class="text-center">2</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">2</td>
<td class="text-center">
<a onclick="showClassDetail('c7', 4)">Detail</a>
</td>
</tr>
<tr id='ft7.1' class='none bg-danger'>
<tr id='st7.1' class='none bg-warning'>
<td>
<div class='testcase'>test_SSL_None_setup_error</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft7.1')">FAIL</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_st7.1')">SKIP</a>
</div>
<!--css div popup start-->
<div id='div_ft7.1' class="popup_window test_output" style="display:none;">
<div id='div_st7.1' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_ft7.1').style.display='none'"><span
onclick="document.getElementById('div_st7.1').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">ft7.1: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_email_ssl.py", line 129, in test_SSL_None_setup_error
self.assertEqual('Failed', ret[-1]['result'])
AssertionError: 'Failed' != 'Started'
- Failed
+ Started</pre>
<pre class="text-left">st7.1: AsyncIO has no ssl handshake timeout</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='ft7.2' class='none bg-danger'>
<tr id='st7.2' class='none bg-warning'>
<td>
<div class='testcase'>test_SSL_STARTTLS_setup_error</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft7.2')">FAIL</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_st7.2')">SKIP</a>
</div>
<!--css div popup start-->
<div id='div_ft7.2' class="popup_window test_output" style="display:none;">
<div id='div_st7.2' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_ft7.2').style.display='none'"><span
onclick="document.getElementById('div_st7.2').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">ft7.2: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_email_ssl.py", line 109, in test_SSL_STARTTLS_setup_error
self.assertEqual(ret[-1]['result'], 'Failed')
AssertionError: 'Waiting' != 'Failed'
- Waiting
+ Failed</pre>
<pre class="text-left">st7.2: AsyncIO has no ssl handshake timeout</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='ft7.3' class='none bg-danger'>
<tr id='pt7.3' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_SSL_logging_email</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft7.3')">FAIL</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_pt7.3')">PASS</a>
</div>
<!--css div popup start-->
<div id='div_ft7.3' class="popup_window test_output" style="display:none;">
<div id='div_pt7.3' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_ft7.3').style.display='none'"><span
onclick="document.getElementById('div_pt7.3').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">ft7.3: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_email_ssl.py", line 137, in test_SSL_logging_email
self.assertTrue(len(re.findall('Subject: Calibre-Web test e-mail',data)),"Email logging not working")
AssertionError: 0 is not true : Email logging not working</pre>
<pre class="text-left">pt7.3: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 38658)
Message addressed from: name@host.com
Message addressed to: a5@b.com
Message length : 42</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='ft7.4' class='none bg-danger'>
<tr id='pt7.4' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_SSL_only</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft7.4')">FAIL</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_pt7.4')">PASS</a>
</div>
<!--css div popup start-->
<div id='div_ft7.4' class="popup_window test_output" style="display:none;">
<div id='div_pt7.4' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_ft7.4').style.display='none'"><span
onclick="document.getElementById('div_pt7.4').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">ft7.4: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_email_ssl.py", line 88, in test_SSL_only
self.assertEqual(ret[-1]['result'], 'Finished')
AssertionError: 'Waiting' != 'Finished'
- Waiting
+ Finished</pre>
<pre class="text-left">pt7.4: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 38660)
Message addressed from: name@host.com
Message addressed to: a1@b.com
Message length : 22013</pre>
</div>
<div class="clearfix"></div>
</div>
@ -1989,12 +1976,12 @@ AssertionError: False is not true : logfile config value is not empty after rese
<!--css div popup end-->
</td>
</tr>
<tr class='errorClass'>
<tr class='skipClass'>
<td>test_register.test_register</td>
<td class="text-center">5</td>
<td class="text-center">2</td>
<td class="text-center">4</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">2</td>
<td class="text-center">1</td>
<td class="text-center">
<a onclick="showClassDetail('c12', 5)">Detail</a>
@ -2029,36 +2016,32 @@ AssertionError: False is not true : logfile config value is not empty after rese
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id='et12.3' class='none bg-info'>
<tr id='pt12.3' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_registering_user</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et12.3')">ERROR</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_pt12.3')">PASS</a>
</div>
<!--css div popup start-->
<div id='div_et12.3' class="popup_window test_output" style="display:none;">
<div id='div_pt12.3' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_et12.3').style.display='none'"><span
onclick="document.getElementById('div_pt12.3').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">et12.3: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 36440)
<pre class="text-left">pt12.3: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 45484)
Message addressed from: name@host.com
Message addressed to: huj@de.de
Message length : 1Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_register.py", line 80, in test_registering_user
user, passw = self.email_server.handler.extract_register_info()
File "/home/matthias/Entwicklung/calibre-web-test/test/email_convert_helper.py", line 90, in extract_register_info
self.message = email.message_from_string(self.message).get_payload(0).get_payload(decode=True).decode('utf-8')
File "/usr/lib/python3.6/email/__init__.py", line 38, in message_from_string
return Parser(*args, **kws).parsestr(s)
File "/usr/lib/python3.6/email/parser.py", line 68, in parsestr
return self.parse(StringIO(text), headersonly=headersonly)
TypeError: initial_value must be str or None, not list</pre>
Message length : 276
User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 45498)
Message addressed from: name@host.com
Message addressed to: huij@de.de
Message length : 284</pre>
</div>
<div class="clearfix"></div>
</div>
@ -2082,118 +2065,75 @@ TypeError: initial_value must be str or None, not list</pre>
</div>
<div class="text-left pull-left">
<pre class="text-left">pt12.4: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 36442)
Receiving message from: ('127.0.0.1', 45500)
Message addressed from: name@host.com
Message addressed to: huj@de.com
Message length : 1</pre>
Message length : 286</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='et12.5' class='none bg-info'>
<tr id='pt12.5' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_user_change_password</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et12.5')">ERROR</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_pt12.5')">PASS</a>
</div>
<!--css div popup start-->
<div id='div_et12.5' class="popup_window test_output" style="display:none;">
<div id='div_pt12.5' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_et12.5').style.display='none'"><span
onclick="document.getElementById('div_pt12.5').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">et12.5: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 36444)
<pre class="text-left">pt12.5: User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 45502)
Message addressed from: name@host.com
Message addressed to: passwd@de.com
Message length : 1Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_register.py", line 118, in test_user_change_password
user, passw = self.email_server.handler.extract_register_info()
File "/home/matthias/Entwicklung/calibre-web-test/test/email_convert_helper.py", line 90, in extract_register_info
self.message = email.message_from_string(self.message).get_payload(0).get_payload(decode=True).decode('utf-8')
File "/usr/lib/python3.6/email/__init__.py", line 38, in message_from_string
return Parser(*args, **kws).parsestr(s)
File "/usr/lib/python3.6/email/parser.py", line 68, in parsestr
return self.parse(StringIO(text), headersonly=headersonly)
TypeError: initial_value must be str or None, not list</pre>
Message length : 286
User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 45504)
Message addressed from: name@host.com
Message addressed to: passwd@de.com
Message length : 212
User: name@host.com, Password: 10234
Receiving message from: ('127.0.0.1', 45506)
Message addressed from: name@host.com
Message addressed to: passwd@de.com
Message length : 212</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr class='errorClass'>
<tr class='failClass'>
<td>test_shelf.test_shelf</td>
<td class="text-center">7</td>
<td class="text-center">5</td>
<td class="text-center">2</td>
<td class="text-center">1</td>
<td class="text-center">4</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">
<a onclick="showClassDetail('c13', 7)">Detail</a>
</td>
</tr>
<tr id='et13.1' class='none bg-info'>
<tr id='pt13.1' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_delete_book_of_shelf</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et13.1')">ERROR</a>
</div>
<!--css div popup start-->
<div id='div_et13.1' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_et13.1').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">et13.1: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_shelf.py", line 205, in test_delete_book_of_shelf
self.get_book_details(books[1][7]['id'])
File "/home/matthias/Entwicklung/calibre-web-test/test/ui_helper.py", line 669, in get_book_details
if id&gt;0:
TypeError: '&gt;' not supported between instances of 'str' and 'int'</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id='et13.2' class='none bg-info'>
<tr id='pt13.2' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_private_shelf</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et13.2')">ERROR</a>
</div>
<!--css div popup start-->
<div id='div_et13.2' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_et13.2').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">et13.2: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_shelf.py", line 70, in test_private_shelf
details = self.get_book_details(books[1][0]['id'])
File "/home/matthias/Entwicklung/calibre-web-test/test/ui_helper.py", line 669, in get_book_details
if id&gt;0:
TypeError: '&gt;' not supported between instances of 'str' and 'int'</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id='pt13.3' class='hiddenRow bg-success'>
<td>
@ -2201,61 +2141,37 @@ TypeError: '&gt;' not supported between instances of 'str' and 'int'</pre>
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id='et13.4' class='none bg-info'>
<tr id='ft13.4' class='none bg-danger'>
<td>
<div class='testcase'>test_public_shelf</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et13.4')">ERROR</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft13.4')">FAIL</a>
</div>
<!--css div popup start-->
<div id='div_et13.4' class="popup_window test_output" style="display:none;">
<div id='div_ft13.4' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_et13.4').style.display='none'"><span
onclick="document.getElementById('div_ft13.4').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">et13.4: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_shelf.py", line 109, in test_public_shelf
details = self.get_book_details(books[1][0]['id'])
File "/home/matthias/Entwicklung/calibre-web-test/test/ui_helper.py", line 669, in get_book_details
if id&gt;0:
TypeError: '&gt;' not supported between instances of 'str' and 'int'</pre>
<pre class="text-left">ft13.4: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_shelf.py", line 121, in test_public_shelf
self.assertTrue(len(shelf_books[0]) == 2)
AssertionError: False is not true</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='et13.5' class='none bg-info'>
<tr id='pt13.5' class='hiddenRow bg-success'>
<td>
<div class='testcase'>test_rename_shelf</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et13.5')">ERROR</a>
</div>
<!--css div popup start-->
<div id='div_et13.5' class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick="document.getElementById('div_et13.5').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">et13.5: Traceback (most recent call last):
File "/home/matthias/Entwicklung/calibre-web-test/test/test_shelf.py", line 148, in test_rename_shelf
self.get_book_details(books[1][0]['id'])
File "/home/matthias/Entwicklung/calibre-web-test/test/ui_helper.py", line 669, in get_book_details
if id&gt;0:
TypeError: '&gt;' not supported between instances of 'str' and 'int'</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id='ft13.6' class='none bg-danger'>
<td>
@ -2852,16 +2768,16 @@ AssertionError: 'Not Implemented' is not None : Database change</pre>
<tr id='total_row' class="text-center bg-grey">
<td>Total</td>
<td>162</td>
<td>95</td>
<td>7</td>
<td>6</td>
<td>54</td>
<td>103</td>
<td>3</td>
<td>0</td>
<td>56</td>
<td>&nbsp;</td>
</tr>
</table>
<script>
drawCircle(95, 7, 6, 54);
drawCircle(103, 3, 0, 56);
</script>
</div>