openSUSE Commits
Threads by month
- ----- 2025 -----
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
June 2018
- 1 participants
- 1694 discussions
Hello community,
here is the log from the commit of package yast2-iplb for openSUSE:Factory checked in at 2018-06-29 22:37:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-iplb (Old)
and /work/SRC/openSUSE:Factory/.yast2-iplb.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-iplb"
Fri Jun 29 22:37:16 2018 rev:8 rq:619789 version:4.0.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-iplb/yast2-iplb.changes 2018-02-14 10:52:08.116575446 +0100
+++ /work/SRC/openSUSE:Factory/.yast2-iplb.new/yast2-iplb.changes 2018-06-29 22:37:18.261954741 +0200
@@ -1,0 +2,6 @@
+Tue Jun 26 17:02:38 CEST 2018 - schubi(a)suse.de
+
+- Added additional searchkeys to desktop file (fate#321043).
+- Version 4.0.1
+
+-------------------------------------------------------------------
Old:
----
yast2-iplb-4.0.0.tar.bz2
New:
----
yast2-iplb-4.0.1.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast2-iplb.spec ++++++
--- /var/tmp/diff_new_pack.zciZUh/_old 2018-06-29 22:37:19.053954054 +0200
+++ /var/tmp/diff_new_pack.zciZUh/_new 2018-06-29 22:37:19.053954054 +0200
@@ -17,7 +17,7 @@
Name: yast2-iplb
-Version: 4.0.0
+Version: 4.0.1
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
++++++ yast2-iplb-4.0.0.tar.bz2 -> yast2-iplb-4.0.1.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-iplb-4.0.0/package/yast2-iplb.changes new/yast2-iplb-4.0.1/package/yast2-iplb.changes
--- old/yast2-iplb-4.0.0/package/yast2-iplb.changes 2018-02-13 16:30:57.000000000 +0100
+++ new/yast2-iplb-4.0.1/package/yast2-iplb.changes 2018-06-29 16:32:58.000000000 +0200
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Tue Jun 26 17:02:38 CEST 2018 - schubi(a)suse.de
+
+- Added additional searchkeys to desktop file (fate#321043).
+- Version 4.0.1
+
+-------------------------------------------------------------------
Sun Feb 11 03:17:49 UTC 2018 - nwang(a)suse.com
- bsc#1080332, split large strings into smaller combination
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-iplb-4.0.0/package/yast2-iplb.spec new/yast2-iplb-4.0.1/package/yast2-iplb.spec
--- old/yast2-iplb-4.0.0/package/yast2-iplb.spec 2018-02-13 16:30:57.000000000 +0100
+++ new/yast2-iplb-4.0.1/package/yast2-iplb.spec 2018-06-29 16:32:58.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-iplb
-Version: 4.0.0
+Version: 4.0.1
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-iplb-4.0.0/src/desktop/iplb.desktop new/yast2-iplb-4.0.1/src/desktop/iplb.desktop
--- old/yast2-iplb-4.0.0/src/desktop/iplb.desktop 2018-02-13 16:30:57.000000000 +0100
+++ new/yast2-iplb-4.0.1/src/desktop/iplb.desktop 2018-06-29 16:32:58.000000000 +0200
@@ -14,6 +14,7 @@
X-SuSE-YaST-Geometry=
X-SuSE-YaST-SortKey=
X-SuSE-YaST-AutoInstResource=iplb
+X-SuSE-YaST-Keywords=network,ip,loadbalancing
Icon=yast-iplb
Exec=/sbin/yast2 iplb
1
0
Hello community,
here is the log from the commit of package osc for openSUSE:Factory checked in at 2018-06-29 22:37:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/osc (Old)
and /work/SRC/openSUSE:Factory/.osc.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "osc"
Fri Jun 29 22:37:10 2018 rev:126 rq:619777 version:0.162.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/osc/osc.changes 2017-12-07 13:54:32.219760789 +0100
+++ /work/SRC/openSUSE:Factory/.osc.new/osc.changes 2018-06-29 22:37:15.169957426 +0200
@@ -1,0 +2,8 @@
+Fri Jun 29 07:23:57 UTC 2018 - marco.strigl(a)suse.com
+
+- add Requires: python2 for Tumbleweed.
+ Otherwise just python-base is installed which does not contain ssl.py
+ [bnc#1097996]
+- removed duplicate entry in appimage.yml to prevent double builds
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ osc.spec ++++++
--- /var/tmp/diff_new_pack.6uiyWH/_old 2018-06-29 22:37:15.961956738 +0200
+++ /var/tmp/diff_new_pack.6uiyWH/_new 2018-06-29 22:37:15.965956734 +0200
@@ -1,7 +1,7 @@
#
# spec file for package osc
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
Version: 0.162.1
Release: 0
Summary: Open Build Service Commander
-License: GPL-2.0+
+License: GPL-2.0-or-later
Group: Development/Tools/Other
Url: https://github.com/openSUSE/osc
Source: %{name}-%{version}.tar.gz
@@ -43,6 +43,11 @@
%endif
#
%if 0%{?suse_version}
+%if 0%{?suse_version} >= 1500
+Requires: python2
+%else
+Requires: python
+%endif
%if 0%{?suse_version} < 1020
BuildRequires: python-elementtree
Requires: python-elementtree
++++++ appimage.yml ++++++
--- /var/tmp/diff_new_pack.6uiyWH/_old 2018-06-29 22:37:16.001956703 +0200
+++ /var/tmp/diff_new_pack.6uiyWH/_new 2018-06-29 22:37:16.005956700 +0200
@@ -27,6 +27,5 @@
- echo "Icon=appimage" >> $BUILD_APPDIR/usr/share/applications/osc.desktop
- echo "Type=Application" >> $BUILD_APPDIR/usr/share/applications/osc.desktop
- linuxdeployqt $BUILD_APPDIR/usr/share/applications/*.desktop -bundle-non-qt-libs -verbose=2
- - linuxdeployqt $BUILD_APPDIR/usr/share/applications/*.desktop -bundle-non-qt-libs -verbose=2
1
0
Hello community,
here is the log from the commit of package xrdp for openSUSE:Factory checked in at 2018-06-29 22:37:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xrdp (Old)
and /work/SRC/openSUSE:Factory/.xrdp.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xrdp"
Fri Jun 29 22:37:06 2018 rev:18 rq:619775 version:0.9.7
Changes:
--------
--- /work/SRC/openSUSE:Factory/xrdp/xrdp.changes 2018-04-16 15:45:55.276778678 +0200
+++ /work/SRC/openSUSE:Factory/.xrdp.new/xrdp.changes 2018-06-29 22:37:10.485961492 +0200
@@ -1,0 +2,21 @@
+Fri Jun 29 12:37:10 UTC 2018 - fezhang(a)suse.com
+
+- Update to version 0.9.7
+ + Bug fixes
+ - Fix endianness detection on ppc64el #1082
+ - Fix a bug xrdp file copy slow #1112 #1132
+ - Copy the PAM session environment for the reconnect script
+ #1120
+ - Accept fullpath for DefaultWindowManager, ReconnectScript
+ #1147
+ + Other changes
+ - Show OpenSSL version to '--version' CLI option #1096
+ - Support sesrun start xorgxrdp sessions #1108
+ - Show configure summary when configure is done #1126 #1134
+ #1137
+ - Less spit on the console when sesman starts #1142
+ - Fix memory leaks #1146
+ - Separate rc script for FreeBSD into xrdp and xrdp-sesman
+ #1153
+
+-------------------------------------------------------------------
Old:
----
xrdp-0.9.6.tar.gz
xrdp-0.9.6.tar.gz.asc
New:
----
xrdp-0.9.7.tar.gz
xrdp-0.9.7.tar.gz.asc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ xrdp.spec ++++++
--- /var/tmp/diff_new_pack.HwVU7B/_old 2018-06-29 22:37:11.217960856 +0200
+++ /var/tmp/diff_new_pack.HwVU7B/_new 2018-06-29 22:37:11.217960856 +0200
@@ -23,7 +23,7 @@
%define _fwdefdir %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services
Name: xrdp
-Version: 0.9.6
+Version: 0.9.7
Release: 0
Summary: Remote desktop protocol (RDP) server
License: Apache-2.0 AND GPL-2.0-or-later
++++++ xrdp-0.9.6.tar.gz -> xrdp-0.9.7.tar.gz ++++++
++++ 27188 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package sqlitebrowser for openSUSE:Factory checked in at 2018-06-29 22:37:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sqlitebrowser (Old)
and /work/SRC/openSUSE:Factory/.sqlitebrowser.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sqlitebrowser"
Fri Jun 29 22:37:01 2018 rev:10 rq:619772 version:3.10.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/sqlitebrowser/sqlitebrowser.changes 2017-09-04 12:30:36.955654839 +0200
+++ /work/SRC/openSUSE:Factory/.sqlitebrowser.new/sqlitebrowser.changes 2018-06-29 22:37:05.769965586 +0200
@@ -1,0 +2,29 @@
+Fri Jun 29 11:00:50 UTC 2018 - wbauer(a)tmo.at
+
+- update to version 3.10.1
+ * Bug fixes
+ - General
+ + cipher: Fix passphrases containing single quotes
+ + cipher: Change tab order in encryption dialog
+ + Fix typo in Russian translation
+ + Pass /norestart to vcredist installer
+ + Fix index updating when removing an indexed column from a table
+ + Don't automatically commit all changes when editing a table column
+ + Make text selectable in Edit dock even if db is opened as read only
+ + Add '<>NULL' filter
+ + Fix custom type saving when only focus changes for user-entered type
+ - DBHub.io related
+ + dbhub: Tweak certificate UI in the preferences dialog
+ + dbhub: Fix progress dialog for very large files
+ + dbhub: Remove closing "." from the progress dialog
+ + dbhub: Ask user what to do when trying to open an updated database
+ + dbhub: Enforce name and commit message length limits in push dialog
+ + dbhub: Add tooltip to cog tool button
+ + dbhub: Redownload database if local copy has been deleted
+ + dbhub: Fix wrong file size being shown for very large files
+ + dbhub: Support pushing to different branches than "master"
+ + dbhub: Improve file size format
+ + dbhub: Optimise code
+ + dbhub: Fix branch list in push dialog
+
+-------------------------------------------------------------------
Old:
----
sqlitebrowser-3.10.0.tar.gz
New:
----
sqlitebrowser-3.10.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ sqlitebrowser.spec ++++++
--- /var/tmp/diff_new_pack.RbAmbO/_old 2018-06-29 22:37:06.429965013 +0200
+++ /var/tmp/diff_new_pack.RbAmbO/_new 2018-06-29 22:37:06.433965010 +0200
@@ -1,7 +1,7 @@
#
# spec file for package sqlitebrowser
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: sqlitebrowser
-Version: 3.10.0
+Version: 3.10.1
Release: 0
Summary: Create, design and edit SQLite Databases
License: GPL-3.0+ AND MPL-2.0
++++++ sqlitebrowser-3.10.0.tar.gz -> sqlitebrowser-3.10.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/CMakeLists.txt new/sqlitebrowser-3.10.1/CMakeLists.txt
--- old/sqlitebrowser-3.10.0/CMakeLists.txt 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/CMakeLists.txt 2017-09-20 15:59:51.000000000 +0200
@@ -413,7 +413,7 @@
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION_MAJOR "3")
set(CPACK_PACKAGE_VERSION_MINOR "10")
-set(CPACK_PACKAGE_VERSION_PATCH "0")
+set(CPACK_PACKAGE_VERSION_PATCH "1")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "DB Browser for SQLite")
if(WIN32 AND NOT UNIX)
# There is a bug in NSIS that does not handle full unix paths properly. Make
@@ -433,7 +433,7 @@
# VS redist
list(APPEND CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
- ExecWait '\\\"$INSTDIR\\\\redist\\\\${VSREDIST}\\\" /install /passive /quiet'
+ ExecWait '\\\"$INSTDIR\\\\redist\\\\${VSREDIST}\\\" /install /passive /norestart /quiet'
Delete '\\\"$INSTDIR\\\\redist\\\\${VSREDIST}\\\"'
")
else(WIN32 AND NOT UNIX)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/CipherDialog.cpp new/sqlitebrowser-3.10.1/src/CipherDialog.cpp
--- old/sqlitebrowser-3.10.0/src/CipherDialog.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/CipherDialog.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -40,7 +40,7 @@
QString CipherDialog::password() const
{
if(keyFormat() == KeyFormats::Passphrase)
- return QString("'%1'").arg(ui->editPassword->text());
+ return QString("'%1'").arg(ui->editPassword->text().replace("'", "''"));
else
return QString("\"x'%1'\"").arg(ui->editPassword->text().mid(2)); // Remove the '0x' part at the beginning
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/CipherDialog.ui new/sqlitebrowser-3.10.1/src/CipherDialog.ui
--- old/sqlitebrowser-3.10.0/src/CipherDialog.ui 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/CipherDialog.ui 2017-09-20 15:59:51.000000000 +0200
@@ -126,8 +126,8 @@
</layout>
</widget>
<tabstops>
- <tabstop>comboKeyFormat</tabstop>
<tabstop>editPassword</tabstop>
+ <tabstop>comboKeyFormat</tabstop>
<tabstop>editPassword2</tabstop>
<tabstop>spinPageSize</tabstop>
</tabstops>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/EditDialog.cpp new/sqlitebrowser-3.10.1/src/EditDialog.cpp
--- old/sqlitebrowser-3.10.0/src/EditDialog.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/EditDialog.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -464,6 +464,8 @@
ui->buttonApply->setEnabled(!ro);
ui->buttonNull->setEnabled(!ro);
ui->buttonImport->setEnabled(!ro);
+ ui->editorText->setReadOnly(ro);
+ ui->editorBinary->setEnabled(!ro); // We disable the entire hex editor here instead of setting it to read only because it doesn't have a setReadOnly() method
}
// Update the information labels in the bottom left corner of the dialog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/EditTableDialog.cpp new/sqlitebrowser-3.10.1/src/EditTableDialog.cpp
--- old/sqlitebrowser-3.10.0/src/EditTableDialog.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/EditTableDialog.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -114,6 +114,7 @@
index = typeBox->count() - 1;
}
typeBox->setCurrentIndex(index);
+ typeBox->installEventFilter(this);
connect(typeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTypes()));
ui->treeWidget->setItemWidget(tbitem, kType, typeBox);
@@ -222,13 +223,13 @@
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
}
-void EditTableDialog::updateTypes()
+void EditTableDialog::updateTypes(QObject *object)
{
- QComboBox* typeBox = qobject_cast<QComboBox*>(sender());
+ QComboBox* typeBox = qobject_cast<QComboBox*>(object);
if(typeBox)
{
QString type = typeBox->currentText();
- QString column = sender()->property("column").toString();
+ QString column = typeBox->property("column").toString();
int index;
for(index=0; index < m_table.fields().size(); ++index)
@@ -244,6 +245,20 @@
}
}
+void EditTableDialog::updateTypes()
+{
+ updateTypes(sender());
+}
+
+bool EditTableDialog::eventFilter(QObject *object, QEvent *event)
+{
+ if(event->type() == QEvent::FocusOut)
+ {
+ updateTypes(object);
+ }
+ return false;
+}
+
void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
{
int index = ui->treeWidget->indexOfTopLevelItem(item);
@@ -528,6 +543,7 @@
}
ui->treeWidget->setItemWidget(tbitem, kType, typeBox);
+ typeBox->installEventFilter(this);
connect(typeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTypes()));
tbitem->setCheckState(kNotNull, Qt::Unchecked);
@@ -631,7 +647,8 @@
QComboBox* oldCombo = qobject_cast<QComboBox*>(ui->treeWidget->itemWidget(ui->treeWidget->topLevelItem(currentRow), kType));
QComboBox* newCombo = new QComboBox(ui->treeWidget);
newCombo->setProperty("column", oldCombo->property("column"));
- connect(newCombo, SIGNAL(activated(int)), this, SLOT(updateTypes()));
+ newCombo->installEventFilter(this);
+ connect(newCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTypes()));
newCombo->setEditable(true);
for(int i=0; i < oldCombo->count(); ++i)
newCombo->addItem(oldCombo->itemText(i));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/EditTableDialog.h new/sqlitebrowser-3.10.1/src/EditTableDialog.h
--- old/sqlitebrowser-3.10.0/src/EditTableDialog.h 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/EditTableDialog.h 2017-09-20 15:59:51.000000000 +0200
@@ -51,6 +51,8 @@
virtual void reject();
void checkInput();
void itemChanged(QTreeWidgetItem* item, int column);
+ void updateTypes(QObject *object);
+ bool eventFilter(QObject *object, QEvent *event);
void updateTypes();
void moveUp();
void moveDown();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/MainWindow.cpp new/sqlitebrowser-3.10.1/src/MainWindow.cpp
--- old/sqlitebrowser-3.10.0/src/MainWindow.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/MainWindow.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -111,6 +111,9 @@
ui->dockPlot->setWidget(plotDock);
ui->dockRemote->setWidget(remoteDock);
+ // Set up edit dock
+ editDock->setReadOnly(true);
+
// Restore window geometry
restoreGeometry(Settings::getValue("MainWindow", "geometry").toByteArray());
restoreState(Settings::getValue("MainWindow", "windowState").toByteArray());
@@ -851,7 +854,7 @@
}
// * Don't allow editing of other objects than tables (on the browse table) *
- bool isEditingAllowed = (m_currentTabTableModel == m_browseTableModel) &&
+ bool isEditingAllowed = !db.readOnly() && m_currentTabTableModel == m_browseTableModel &&
(db.getObjectByName(ui->comboBrowseTable->currentText())->type() == sqlb::Object::Types::Table);
// Enable or disable the Apply, Null, & Import buttons in the Edit Cell
@@ -875,7 +878,7 @@
return;
}
- bool editingAllowed = (m_currentTabTableModel == m_browseTableModel) &&
+ bool editingAllowed = !db.readOnly() && (m_currentTabTableModel == m_browseTableModel) &&
(db.getObjectByName(ui->comboBrowseTable->currentText())->type() == sqlb::Object::Types::Table);
// Don't allow editing of other objects than tables
@@ -1486,7 +1489,7 @@
ui->actionSaveProject->setEnabled(enable);
ui->actionEncryption->setEnabled(enable && write);
ui->buttonClearFilters->setEnabled(enable);
- ui->dockEdit->setEnabled(enable && write);
+ ui->dockEdit->setEnabled(enable);
ui->dockPlot->setEnabled(enable);
remoteDock->enableButtons();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/PreferencesDialog.ui new/sqlitebrowser-3.10.1/src/PreferencesDialog.ui
--- old/sqlitebrowser-3.10.0/src/PreferencesDialog.ui 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/PreferencesDialog.ui 2017-09-20 15:59:51.000000000 +0200
@@ -1035,6 +1035,9 @@
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
<column>
<property name="text">
<string>Subject CN</string>
@@ -1094,6 +1097,9 @@
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
<column>
<property name="text">
<string>File</string>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemoteDatabase.cpp new/sqlitebrowser-3.10.1/src/RemoteDatabase.cpp
--- old/sqlitebrowser-3.10.0/src/RemoteDatabase.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemoteDatabase.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -181,6 +181,27 @@
emit gotLicenceList(licences);
break;
}
+ case RequestTypeBranchList:
+ {
+ // Read and check results
+ QJsonDocument json = QJsonDocument::fromJson(reply->readAll());
+ if(json.isNull() || !json.isObject())
+ break;
+ QJsonObject obj = json.object();
+ QJsonObject obj_branches = obj["branches"].toObject();
+
+ // Parse data and assemble branch list
+ QStringList branches;
+ for(auto it=obj_branches.constBegin();it!=obj_branches.constEnd();++it)
+ branches.append(it.key());
+
+ // Get default branch
+ QString default_branch = obj["default_branch"].toString("master");
+
+ // Send branch list to anyone who is interested
+ emit gotBranchList(branches, default_branch);
+ break;
+ }
case RequestTypePush:
emit uploadFinished(reply->url().toString());
break;
@@ -238,9 +259,14 @@
m_progress->reset();
} else {
// It's still downloading and we know the current progress
+
+ // Were using a range 0 to 10000 here, the progress dialog will calculate 0% to 100% values from that. The reason we're not using
+ // the byte counts as-is is that they're 64bit wide while the progress dialog takes only 32bit values, so for large files the values
+ // would lose precision. The reason why we're not using a range 0 to 100 is that our range increases the precision a bit and this way
+ // we're prepared if the progress dialog will show decimal numbers one day on one platform.
m_progress->setMinimum(0);
- m_progress->setMaximum(bytesTotal);
- m_progress->setValue(bytesTransmitted);
+ m_progress->setMaximum(10000);
+ m_progress->setValue(static_cast<int>((static_cast<float>(bytesTransmitted) / static_cast<float>(bytesTotal)) * 10000.0f));
}
// Check if the Cancel button has been pressed
@@ -320,9 +346,9 @@
// Set dialog text
if(upload)
- m_progress->setLabelText(tr("Uploading remote database to\n%1.").arg(url));
+ m_progress->setLabelText(tr("Uploading remote database to\n%1").arg(url));
else
- m_progress->setLabelText(tr("Downloading remote database from\n%1.").arg(url));
+ m_progress->setLabelText(tr("Downloading remote database from\n%1").arg(url));
// Show dialog
m_progress->show();
@@ -387,7 +413,7 @@
}
void RemoteDatabase::push(const QString& filename, const QString& url, const QString& clientCert, const QString& remotename,
- const QString& commitMessage, const QString& licence, bool isPublic)
+ const QString& commitMessage, const QString& licence, bool isPublic, const QString& branch)
{
// Check if network is accessible. If not, abort right here
if(m_manager->networkAccessible() == QNetworkAccessManager::NotAccessible)
@@ -416,6 +442,7 @@
addPart(multipart, "commitmsg", commitMessage);
addPart(multipart, "licence", licence);
addPart(multipart, "public", isPublic ? "true" : "false");
+ addPart(multipart, "branch", branch);
// Set SSL configuration when trying to access a file via the HTTPS protocol
bool https = QUrl(url).scheme().compare("https", Qt::CaseInsensitive) == 0;
@@ -574,8 +601,6 @@
// Extract commit id from url and remove query part afterwards
QString url_commit_id = QUrlQuery(url).queryItemValue("commit");
- QUrl url_without_query = url;
- url_without_query.setQuery(QString());
// Query commit id and filename for the given combination of url and identity
QString sql = QString("SELECT id, commit_id, file FROM local WHERE url=? AND identity=?");
@@ -583,7 +608,7 @@
if(sqlite3_prepare_v2(m_dbLocal, sql.toUtf8(), -1, &stmt, 0) != SQLITE_OK)
return QString();
- if(sqlite3_bind_text(stmt, 1, url_without_query.toString().toUtf8(), url_without_query.toString().toUtf8().length(), SQLITE_TRANSIENT))
+ if(sqlite3_bind_text(stmt, 1, url.toString(QUrl::PrettyDecoded | QUrl::RemoveQuery).toUtf8(), url.toString(QUrl::PrettyDecoded | QUrl::RemoveQuery).toUtf8().length(), SQLITE_TRANSIENT))
{
sqlite3_finalize(stmt);
return QString();
@@ -616,15 +641,79 @@
// is newer, or the local commit id is newer.
if(local_commit_id == url_commit_id)
{
- // Both commit ids are the same. That's the perfect match, so just return the path to the local file
- return Settings::getValue("remote", "clonedirectory").toString() + "/" + local_file;
+ // Both commit ids are the same. That's the perfect match, so we can download the local file if it still exists
+ return localCheckFile(local_file);
} else {
- // In all the other cases just treat the remote database as a completely new database for now.
+ // The commit ids differ. That means we have another version locally checked out than we're trying to download. Because the commit ids are
+ // only calculated on the server side and we're currently always checking out the latest version this can only mean that the remote version has
+ // been updated, i.e. is newer than the local version.
+
+ // TODO Support multiple checkouts of the same database at different versions at the same time. For this we need to be more intelligent with
+ // comparing the commit ids.
+
+ // Ask the user what to do: open the local version or updating to the new remote version
+ if(QMessageBox::question(nullptr, qApp->applicationName(),
+ tr("The remote database has been updated since the last checkout. Do you want to update the local database to the newest version? Note "
+ "that this discards any changes you have made locally! If you don't want to lose local changes, click No to open the local version."),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
+ {
+ // User wants to download the newest version. So delete the entry from the clones database and delete the local database copy and return an empty
+ // string to indicate a redownload request.
+
+ // Build full path to database file and delete it
+ QFile::remove(Settings::getValue("remote", "clonedirectory").toString() + "/" + local_file);
- // TODO Add some way to update the local clone here. Maybe ask the user what to do because I don't really know what the
- // most sensible way to go is in the two remaining cases. We can use the local_id variable (see above) to update the
- // record afterwards.
+ // Remove the old entry from the local clones database to enforce a redownload. The file column should be unique for the entire table because the
+ // files are all in the same directory and their names need to be unique because of this.
+ QString sql = QString("DELETE FROM local WHERE file=?");
+ sqlite3_stmt* stmt;
+ if(sqlite3_prepare_v2(m_dbLocal, sql.toUtf8(), -1, &stmt, 0) != SQLITE_OK)
+ return QString();
+ if(sqlite3_bind_text(stmt, 1, local_file.toUtf8(), local_file.toUtf8().length(), SQLITE_TRANSIENT))
+ {
+ sqlite3_finalize(stmt);
+ return QString();
+ }
+ sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+
+ // Return an empty string to indicate a redownload request
+ return QString();
+ } else {
+ // User wants to open the local version. So build the full path and return it if the file still exists.
+ return localCheckFile(local_file);
+ }
+ }
+}
+
+QString RemoteDatabase::localCheckFile(const QString& local_file)
+{
+ // This function takes the file name of a locally cloned database and checks if this file still exists. If it has been deleted in the meantime it returns
+ // an empty string and deletes the file from the clone database. If the file still exists, it returns the full path to the file.
+
+ // Build the full path to where the file should be
+ QString full_path = Settings::getValue("remote", "clonedirectory").toString() + "/" + local_file;
+
+ // Check if the database still exists. If so return its path, if not return an empty string to redownload it
+ if(QFile::exists(full_path))
+ {
+ return full_path;
+ } else {
+ // Remove the apparently invalid entry from the local clones database to avoid future lookups and confusions. The file column should
+ // be unique for the entire table because the files are all in the same directory and their names need to be unique because of this.
+ QString sql = QString("DELETE FROM local WHERE file=?");
+ sqlite3_stmt* stmt;
+ if(sqlite3_prepare_v2(m_dbLocal, sql.toUtf8(), -1, &stmt, 0) != SQLITE_OK)
+ return QString();
+ if(sqlite3_bind_text(stmt, 1, local_file.toUtf8(), local_file.toUtf8().length(), SQLITE_TRANSIENT))
+ {
+ sqlite3_finalize(stmt);
+ return QString();
+ }
+ sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ // Return empty string to indicate a redownload request
return QString();
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemoteDatabase.h new/sqlitebrowser-3.10.1/src/RemoteDatabase.h
--- old/sqlitebrowser-3.10.0/src/RemoteDatabase.h 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemoteDatabase.h 2017-09-20 15:59:51.000000000 +0200
@@ -41,11 +41,12 @@
RequestTypeNewVersionCheck,
RequestTypePush,
RequestTypeLicenceList,
+ RequestTypeBranchList,
};
void fetch(const QString& url, RequestType type, const QString& clientCert = QString(), QVariant userdata = QVariant());
void push(const QString& filename, const QString& url, const QString& clientCert, const QString& remotename,
- const QString& commitMessage = QString(), const QString& licence = QString(), bool isPublic = false);
+ const QString& commitMessage = QString(), const QString& licence = QString(), bool isPublic = false, const QString& branch = QString("master"));
signals:
// The openFile signal is emitted whenever a remote database file shall be opened in the main window. This happens when the
@@ -57,6 +58,7 @@
void gotDirList(QString json, QVariant userdata);
void gotCurrentVersion(QString version, QString url);
void gotLicenceList(QMap<QString, QString> licences);
+ void gotBranchList(QStringList branches, QString default_branch);
// The uploadFinished() signal is emitted when a push() call is finished, i.e. a database upload has completed.
void uploadFinished(QString url);
@@ -73,6 +75,7 @@
void localAssureOpened();
void localAdd(QString filename, QString identity, const QUrl& url);
QString localExists(const QUrl& url, QString identity);
+ QString localCheckFile(const QString& local_file);
// Helper functions for building multi-part HTTP requests
void addPart(QHttpMultiPart* multipart, const QString& name, const QString& value);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemoteDock.cpp new/sqlitebrowser-3.10.1/src/RemoteDock.cpp
--- old/sqlitebrowser-3.10.0/src/RemoteDock.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemoteDock.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -111,7 +111,7 @@
// Push database
remoteDatabase.push(mainWindow->getDb().currentFile(), url, remoteModel->currentClientCertificate(), pushDialog.name(),
- pushDialog.commitMessage(), pushDialog.licence(), pushDialog.isPublic());
+ pushDialog.commitMessage(), pushDialog.licence(), pushDialog.isPublic(), pushDialog.branch());
}
void RemoteDock::newDirectoryNode(const QModelIndex& parent)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemoteDock.ui new/sqlitebrowser-3.10.1/src/RemoteDock.ui
--- old/sqlitebrowser-3.10.0/src/RemoteDock.ui 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemoteDock.ui 2017-09-20 15:59:51.000000000 +0200
@@ -35,6 +35,9 @@
</item>
<item>
<widget class="QToolButton" name="buttonLogin">
+ <property name="toolTip">
+ <string>Connect to the remote server using the currently selected identity. The correct server is taken from the identity as well.</string>
+ </property>
<property name="text">
<string>Go</string>
</property>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemoteModel.cpp new/sqlitebrowser-3.10.1/src/RemoteModel.cpp
--- old/sqlitebrowser-3.10.0/src/RemoteModel.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemoteModel.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -233,7 +233,7 @@
return QVariant();
// Convert size to human readable format
- float size = item->value(RemoteModelColumnSize).toInt();
+ float size = item->value(RemoteModelColumnSize).toLongLong();
QStringList list;
list << "KiB" << "MiB" << "GiB" << "TiB";
QStringListIterator it(list);
@@ -243,7 +243,7 @@
unit = it.next();
size /= 1024.0;
}
- return QString().setNum(size, 'f', 2) + " " + unit;
+ return QString().setNum(size, 'f', 2).remove(".00") + " " + unit;
}
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemotePushDialog.cpp new/sqlitebrowser-3.10.1/src/RemotePushDialog.cpp
--- old/sqlitebrowser-3.10.0/src/RemotePushDialog.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemotePushDialog.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -1,4 +1,5 @@
#include <QPushButton>
+#include <QUrlQuery>
#include "RemotePushDialog.h"
#include "ui_RemotePushDialog.h"
@@ -7,6 +8,8 @@
RemotePushDialog::RemotePushDialog(QWidget* parent, RemoteDatabase& remote, const QString& host, const QString& clientCert, const QString& name) :
QDialog(parent),
ui(new Ui::RemotePushDialog),
+ m_host(host),
+ m_clientCert(clientCert),
remoteDatabase(remote)
{
// Create UI
@@ -21,6 +24,10 @@
// Fetch list of available licences
connect(&remoteDatabase, &RemoteDatabase::gotLicenceList, this, &RemotePushDialog::fillInLicences);
remoteDatabase.fetch(host + "licence/list", RemoteDatabase::RequestTypeLicenceList, clientCert);
+
+ // Prepare fetching list of available branches
+ connect(&remoteDatabase, &RemoteDatabase::gotBranchList, this, &RemotePushDialog::fillInBranches);
+ reloadBranchList();
}
RemotePushDialog::~RemotePushDialog()
@@ -42,6 +49,12 @@
if(ui->editName->text().trimmed().isEmpty())
valid = false;
+ if(ui->editCommitMessage->toPlainText().size() > 1024)
+ valid = false;
+
+ if(ui->comboBranch->currentText().size() < 1 || ui->comboBranch->currentText().size() > 32)
+ valid = false;
+
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
}
@@ -67,7 +80,12 @@
bool RemotePushDialog::isPublic() const
{
- return ui->checkPublic->isChecked();
+ return ui->checkPublic->isChecked();
+}
+
+QString RemotePushDialog::branch() const
+{
+ return ui->comboBranch->currentText();
}
void RemotePushDialog::fillInLicences(const QMap<QString, QString>& licences)
@@ -80,3 +98,31 @@
for(auto it=licences.constBegin();it!=licences.constEnd();++it)
ui->comboLicence->addItem(it.value(), it.key());
}
+
+void RemotePushDialog::fillInBranches(const QStringList& branches, const QString& default_branch)
+{
+ // Clear branch list and add the default branch
+ ui->comboBranch->clear();
+ ui->comboBranch->addItem(default_branch);
+
+ // Add rest of the branch list to the combo box
+ foreach(const QString& branch, branches)
+ {
+ if(branch != default_branch)
+ ui->comboBranch->addItem(branch);
+ }
+}
+
+void RemotePushDialog::reloadBranchList()
+{
+ // Assemble query URL
+ QUrl url(m_host + "branch/list");
+ QUrlQuery query;
+ query.addQueryItem("username", remoteDatabase.getInfoFromClientCert(m_clientCert, RemoteDatabase::CertInfoUser));
+ query.addQueryItem("folder", "/");
+ query.addQueryItem("dbname", ui->editName->text());
+ url.setQuery(query);
+
+ // Send request
+ remoteDatabase.fetch(url.toString(), RemoteDatabase::RequestTypeBranchList, m_clientCert);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemotePushDialog.h new/sqlitebrowser-3.10.1/src/RemotePushDialog.h
--- old/sqlitebrowser-3.10.0/src/RemotePushDialog.h 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemotePushDialog.h 2017-09-20 15:59:51.000000000 +0200
@@ -21,10 +21,15 @@
QString commitMessage() const;
QString licence() const;
bool isPublic() const;
+ QString branch() const;
private:
Ui::RemotePushDialog* ui;
+ // Connection details
+ QString m_host;
+ QString m_clientCert;
+
// Reference to the remote database object which is stored somewhere in the main window
RemoteDatabase& remoteDatabase;
@@ -32,7 +37,10 @@
void checkInput();
virtual void accept();
+ void reloadBranchList();
+
void fillInLicences(const QMap<QString, QString>& licences);
+ void fillInBranches(const QStringList& branches, const QString& default_branch);
};
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/RemotePushDialog.ui new/sqlitebrowser-3.10.1/src/RemotePushDialog.ui
--- old/sqlitebrowser-3.10.0/src/RemotePushDialog.ui 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/RemotePushDialog.ui 2017-09-20 15:59:51.000000000 +0200
@@ -27,7 +27,11 @@
</widget>
</item>
<item row="0" column="1">
- <widget class="QLineEdit" name="editName"/>
+ <widget class="QLineEdit" name="editName">
+ <property name="maxLength">
+ <number>256</number>
+ </property>
+ </widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
@@ -53,7 +57,7 @@
</property>
</widget>
</item>
- <item row="3" column="0">
+ <item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Database licence</string>
@@ -63,7 +67,7 @@
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="4" column="1">
<widget class="QComboBox" name="comboLicence">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -73,7 +77,7 @@
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Public</string>
@@ -83,9 +87,29 @@
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="3" column="1">
<widget class="QCheckBox" name="checkPublic"/>
</item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Branch</string>
+ </property>
+ <property name="buddy">
+ <cstring>comboBranch</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="comboBranch">
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
@@ -103,6 +127,7 @@
<tabstops>
<tabstop>editName</tabstop>
<tabstop>editCommitMessage</tabstop>
+ <tabstop>comboBranch</tabstop>
<tabstop>checkPublic</tabstop>
<tabstop>comboLicence</tabstop>
</tabstops>
@@ -172,8 +197,57 @@
</hint>
</hints>
</connection>
+ <connection>
+ <sender>editCommitMessage</sender>
+ <signal>textChanged()</signal>
+ <receiver>RemotePushDialog</receiver>
+ <slot>checkInput()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>175</x>
+ <y>113</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>91</x>
+ <y>111</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>editName</sender>
+ <signal>editingFinished()</signal>
+ <receiver>RemotePushDialog</receiver>
+ <slot>reloadBranchList()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>176</x>
+ <y>25</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>77</x>
+ <y>3</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>comboBranch</sender>
+ <signal>currentTextChanged(QString)</signal>
+ <receiver>RemotePushDialog</receiver>
+ <slot>checkInput()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>172</x>
+ <y>138</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>33</x>
+ <y>151</y>
+ </hint>
+ </hints>
+ </connection>
</connections>
<slots>
<slot>checkInput()</slot>
+ <slot>reloadBranchList()</slot>
</slots>
</ui>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/app.plist new/sqlitebrowser-3.10.1/src/app.plist
--- old/sqlitebrowser-3.10.0/src/app.plist 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/app.plist 2017-09-20 15:59:51.000000000 +0200
@@ -52,7 +52,7 @@
<key>CFBundleExecutable</key>
<string>@EXECUTABLE@</string>
<key>CFBundleGetInfoString</key>
- <string>3.10.0</string>
+ <string>3.10.1</string>
<key>CFBundleIconFile</key>
<string>@ICON@</string>
<key>CFBundleIdentifier</key>
@@ -64,11 +64,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>3.10.0</string>
+ <string>3.10.1</string>
<key>CFBundleSignature</key>
<string>SqLB</string>
<key>CFBundleVersion</key>
- <string>3.10.0</string>
+ <string>3.10.1</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/sqlitedb.cpp new/sqlitebrowser-3.10.1/src/sqlitedb.cpp
--- old/sqlitebrowser-3.10.0/src/sqlitedb.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/sqlitedb.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -1157,12 +1157,25 @@
if((*it)->type() == sqlb::Object::Types::Index)
{
sqlb::IndexPtr idx = (*it).dynamicCast<sqlb::Index>();
- for(int i=0;i<idx->columns().size();i++)
+
+ // Are we updating a field name or are we removing a field entirely?
+ if(to)
{
- if(idx->column(i)->name() == name)
- idx->column(i)->setName(to->name());
+ // We're updating a field name. So search for it in the index and replace it whereever it is found
+ for(int i=0;i<idx->columns().size();i++)
+ {
+ if(idx->column(i)->name() == name)
+ idx->column(i)->setName(to->name());
+ }
+ } else {
+ // We're removing a field. So remove it from any indices, too.
+ while(idx->removeColumn(name))
+ ;
}
- otherObjectsSql << idx->sql();
+
+ // Only try to add the index later if it has any columns remaining
+ if(idx->columns().size())
+ otherObjectsSql << idx->sql();
} else {
// If it's a view or a trigger we don't have any chance to corrections yet. Just store the statement as is and
// hope for the best.
@@ -1401,7 +1414,13 @@
// Set the pragma value
QString sql = QString("PRAGMA %1 = \"%2\";").arg(pragma).arg(value);
- releaseSavepoint();
+ // In general, we want to commit changes before running pragmas because most of them can't be rolled back and some of them
+ // even fail when run in a transaction. However, the defer_foreign_keys pragma has neither problem and we need it to be settable
+ // inside transactions (see the renameColumn() function where it is set and reset at some point and where we don't want the changes
+ // to be committed just because of this pragma).
+ if(pragma != "defer_foreign_keys")
+ releaseSavepoint();
+
bool res = executeSQL(sql, false, true); // PRAGMA statements are usually not transaction bound, so we can't revert
if( !res )
qWarning() << tr("Error setting pragma %1 to %2: %3").arg(pragma).arg(value).arg(lastErrorMessage);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/sqlitetablemodel.cpp new/sqlitebrowser-3.10.1/src/sqlitetablemodel.cpp
--- old/sqlitebrowser-3.10.0/src/sqlitetablemodel.cpp 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/sqlitetablemodel.cpp 2017-09-20 15:59:51.000000000 +0200
@@ -711,13 +711,23 @@
val2.clear();
if(value.left(2) == ">=" || value.left(2) == "<=" || value.left(2) == "<>")
{
- bool ok;
- value.mid(2).toFloat(&ok);
- if(ok)
+ // Check if we're filtering for '<> NULL'. In this case we need a special comparison operator.
+ if(value.left(2) == "<>" && value.mid(2) == "NULL")
{
- op = value.left(2);
- val = value.mid(2);
+ // We are filtering for '<> NULL'. Override the comparison operator to search for NULL values in this column. Also treat search value (NULL) as number,
+ // in order to avoid putting quotes around it.
+ op = "IS NOT";
numeric = true;
+ val = "NULL";
+ } else {
+ bool ok;
+ value.mid(2).toFloat(&ok);
+ if(ok)
+ {
+ op = value.left(2);
+ val = value.mid(2);
+ numeric = true;
+ }
}
} else if(value.left(1) == ">" || value.left(1) == "<") {
bool ok;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/translations/sqlb_ru.ts new/sqlitebrowser-3.10.1/src/translations/sqlb_ru.ts
--- old/sqlitebrowser-3.10.0/src/translations/sqlb_ru.ts 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/translations/sqlb_ru.ts 2017-09-20 15:59:51.000000000 +0200
@@ -3988,7 +3988,7 @@
<message>
<location filename="../SqlUiLexer.cpp" line="107"/>
<source>(X) The count(X) function returns a count of the number of times that X is not NULL in a group.</source>
- <translation>(X) Функция count(X) возвращает количесвто строк, в которых X не равно NULL в группе.</translation>
+ <translation>(X) Функция count(X) возвращает количество строк, в которых X не равно NULL в группе.</translation>
</message>
<message>
<location filename="../SqlUiLexer.cpp" line="108"/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlitebrowser-3.10.0/src/version.h new/sqlitebrowser-3.10.1/src/version.h
--- old/sqlitebrowser-3.10.0/src/version.h 2017-08-18 20:15:39.000000000 +0200
+++ new/sqlitebrowser-3.10.1/src/version.h 2017-09-20 15:59:51.000000000 +0200
@@ -2,7 +2,7 @@
#define GEN_VERSION_H
#define MAJOR_VERSION 3
#define MINOR_VERSION 10
-#define PATCH_VERSION 0
+#define PATCH_VERSION 1
#define str(s) #s
#define xstr(s) str(s)
1
0
Hello community,
here is the log from the commit of package spec-cleaner for openSUSE:Factory checked in at 2018-06-29 22:36:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/spec-cleaner (Old)
and /work/SRC/openSUSE:Factory/.spec-cleaner.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "spec-cleaner"
Fri Jun 29 22:36:59 2018 rev:53 rq:619757 version:1.0.9
Changes:
--------
--- /work/SRC/openSUSE:Factory/spec-cleaner/spec-cleaner.changes 2018-05-16 11:39:05.765751611 +0200
+++ /work/SRC/openSUSE:Factory/.spec-cleaner.new/spec-cleaner.changes 2018-06-29 22:37:03.617967454 +0200
@@ -1,0 +2,9 @@
+Fri Jun 29 11:19:48 UTC 2018 - tchvatal(a)suse.com
+
+- Version uppdate to 1.0.9 bsc#1099674:
+ * Move some checks from rpmlint to be autochecked
+ * Dropped support of py2
+ * Fixed error reported on parsing non-utf spec-file
+ * Leap 15.0 used as base for conversions to pkgconfig/etc.
+
+-------------------------------------------------------------------
Old:
----
spec-cleaner-1.0.8.tar.gz
New:
----
spec-cleaner-1.0.9.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ spec-cleaner.spec ++++++
--- /var/tmp/diff_new_pack.lt2kHI/_old 2018-06-29 22:37:05.017966238 +0200
+++ /var/tmp/diff_new_pack.lt2kHI/_new 2018-06-29 22:37:05.021966235 +0200
@@ -18,7 +18,7 @@
Name: spec-cleaner
-Version: 1.0.8
+Version: 1.0.9
Release: 0
Summary: .spec file cleaner
License: BSD-3-Clause
@@ -56,6 +56,7 @@
python3 setup.py build
%check
+export LANG=en_US.UTF-8
python3 setup.py test
%install
++++++ spec-cleaner-1.0.8.tar.gz -> spec-cleaner-1.0.9.tar.gz ++++++
++++ 5604 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package docker-kubic for openSUSE:Factory checked in at 2018-06-29 22:36:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/docker-kubic (Old)
and /work/SRC/openSUSE:Factory/.docker-kubic.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "docker-kubic"
Fri Jun 29 22:36:55 2018 rev:13 rq:619751 version:17.09.1_ce
Changes:
--------
--- /work/SRC/openSUSE:Factory/docker-kubic/docker-kubic.changes 2018-06-08 23:17:41.723231616 +0200
+++ /work/SRC/openSUSE:Factory/.docker-kubic.new/docker-kubic.changes 2018-06-29 22:36:58.105972238 +0200
@@ -1,0 +2,9 @@
+Fri Jun 29 08:35:56 UTC 2018 - asarai(a)suse.com
+
+- Update the AppArmor patchset again to fix a separate issue where changed
+ AppArmor profiles don't actually get applied on Docker daemon reboot.
+ bsc#1099277
+ * bsc1073877-0001-apparmor-allow-receiving-of-signals-from-docker-kill.patch
+ + bsc1073877-0002-apparmor-clobber-docker-default-profile-on-start.patch
+
+-------------------------------------------------------------------
New:
----
bsc1073877-0002-apparmor-clobber-docker-default-profile-on-start.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ docker-kubic.spec ++++++
--- /var/tmp/diff_new_pack.tA0cYO/_old 2018-06-29 22:36:58.617971794 +0200
+++ /var/tmp/diff_new_pack.tA0cYO/_new 2018-06-29 22:36:58.621971791 +0200
@@ -68,10 +68,13 @@
Patch400: bsc1055676-0001-daemon-oci-obey-CL_UNPRIVILEGED-for-user-namespaced-.patch
# SUSE-BACKPORT: Backport of https://github.com/moby/moby/pull/35518. bsc#1021227 bsc#1029320 bsc#1058173
Patch401: bsc1021227-0001-pkg-devmapper-dynamically-load-dm_task_deferred_remo.patch
+# SUSE-BACKPORT: Backport of https://github.com/moby/moby/pull/36822. bsc#1073877
+Patch402: bsc1073877-0001-apparmor-allow-receiving-of-signals-from-docker-kill.patch
+# SUSE-BACKPORT: Backport of https://github.com/moby/moby/pull/37353. bsc#1099277
+Patch403: bsc1073877-0002-apparmor-clobber-docker-default-profile-on-start.patch
# SUSE-FEATURE: Add support to mirror inofficial/private registries
# (https://github.com/moby/moby/pull/34319)
Patch500: private-registry-0001-Add-private-registry-mirror-support.patch
-Patch501: bsc1073877-0001-apparmor-allow-receiving-of-signals-from-docker-kill.patch
BuildRequires: audit
BuildRequires: bash-completion
BuildRequires: ca-certificates
@@ -221,10 +224,12 @@
%patch400 -p1
# bsc#1021227 bsc#1029320 bsc#1058173
%patch401 -p1
+# bsc#1073877
+%patch402 -p1
+# bsc#1099277
+%patch403 -p1
# PATCH-SUSE: Mirror patch.
%patch500 -p1
-# bsc#1073877
-%patch501 -p1
cp %{SOURCE7} .
cp %{SOURCE9} .
++++++ bsc1073877-0001-apparmor-allow-receiving-of-signals-from-docker-kill.patch ++++++
--- /var/tmp/diff_new_pack.tA0cYO/_old 2018-06-29 22:36:58.665971753 +0200
+++ /var/tmp/diff_new_pack.tA0cYO/_new 2018-06-29 22:36:58.665971753 +0200
@@ -1,7 +1,7 @@
From 2cc9da975798847cd0a37d1571d8a0f1d72b522d Mon Sep 17 00:00:00 2001
From: Aleksa Sarai <asarai(a)suse.de>
Date: Sun, 8 Apr 2018 20:21:30 +1000
-Subject: [PATCH] apparmor: allow receiving of signals from 'docker kill'
+Subject: [PATCH 1/2] apparmor: allow receiving of signals from 'docker kill'
In newer kernels, AppArmor will reject attempts to send signals to a
container because the signal originated from outside of that AppArmor
@@ -32,5 +32,5 @@
deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)
# deny write to files not in /proc/<number>/** or /proc/sys/**
--
-2.16.3
+2.17.1
++++++ bsc1073877-0002-apparmor-clobber-docker-default-profile-on-start.patch ++++++
>From 8edc54753ab5ea9294c55ec32b49c9eb7cdf3892 Mon Sep 17 00:00:00 2001
From: Aleksa Sarai <asarai(a)suse.de>
Date: Fri, 29 Jun 2018 17:59:30 +1000
Subject: [PATCH 2/2] apparmor: clobber docker-default profile on start
In the process of making docker-default reloading far less expensive,
567ef8e7858c ("daemon: switch to 'ensure' workflow for AppArmor
profiles") mistakenly made the initial profile load at dockerd start-up
lazy. As a result, if you have a running Docker daemon and upgrade it to
a new one with an updated AppArmor profile the new profile will not take
effect (because the old one is still loaded). The fix for this is quite
trivial, and just requires us to clobber the profile on start-up.
Fixes: 567ef8e7858c ("daemon: switch to 'ensure' workflow for AppArmor profiles")
SUSE-Bugs: bsc#1099277
Signed-off-by: Aleksa Sarai <asarai(a)suse.de>
---
components/engine/daemon/apparmor_default.go | 14 ++++++++++----
.../engine/daemon/apparmor_default_unsupported.go | 4 ++++
components/engine/daemon/daemon.go | 4 +++-
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/components/engine/daemon/apparmor_default.go b/components/engine/daemon/apparmor_default.go
index 2a418b25c241..c3e271ee4774 100644
--- a/components/engine/daemon/apparmor_default.go
+++ b/components/engine/daemon/apparmor_default.go
@@ -14,6 +14,15 @@ const (
defaultApparmorProfile = "docker-default"
)
+func clobberDefaultAppArmorProfile() error {
+ if apparmor.IsEnabled() {
+ if err := aaprofile.InstallDefault(defaultApparmorProfile); err != nil {
+ return fmt.Errorf("AppArmor enabled on system but the %s profile could not be loaded: %s", defaultApparmorProfile, err)
+ }
+ }
+ return nil
+}
+
func ensureDefaultAppArmorProfile() error {
if apparmor.IsEnabled() {
loaded, err := aaprofile.IsLoaded(defaultApparmorProfile)
@@ -27,10 +36,7 @@ func ensureDefaultAppArmorProfile() error {
}
// Load the profile.
- if err := aaprofile.InstallDefault(defaultApparmorProfile); err != nil {
- return fmt.Errorf("AppArmor enabled on system but the %s profile could not be loaded: %s", defaultApparmorProfile, err)
- }
+ return clobberDefaultAppArmorProfile()
}
-
return nil
}
diff --git a/components/engine/daemon/apparmor_default_unsupported.go b/components/engine/daemon/apparmor_default_unsupported.go
index cd2dd9702ef2..17584063c711 100644
--- a/components/engine/daemon/apparmor_default_unsupported.go
+++ b/components/engine/daemon/apparmor_default_unsupported.go
@@ -2,6 +2,10 @@
package daemon
+func clobberDefaultAppArmorProfile() error {
+ return nil
+}
+
func ensureDefaultAppArmorProfile() error {
return nil
}
diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go
index a11a1f8691cc..6f8846b19f57 100644
--- a/components/engine/daemon/daemon.go
+++ b/components/engine/daemon/daemon.go
@@ -594,7 +594,9 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
logrus.Warnf("Failed to configure golang's threads limit: %v", err)
}
- if err := ensureDefaultAppArmorProfile(); err != nil {
+ // Make sure we clobber any pre-existing docker-default profile to ensure
+ // that upgrades to the profile actually work smoothly.
+ if err := clobberDefaultAppArmorProfile(); err != nil {
logrus.Errorf(err.Error())
}
--
2.17.1
1
0
Hello community,
here is the log from the commit of package golang-org-x-tools for openSUSE:Factory checked in at 2018-06-29 22:36:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/golang-org-x-tools (Old)
and /work/SRC/openSUSE:Factory/.golang-org-x-tools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "golang-org-x-tools"
Fri Jun 29 22:36:52 2018 rev:2 rq:619747 version:1.9+git20170824.5d2fd3cc
Changes:
--------
--- /work/SRC/openSUSE:Factory/golang-org-x-tools/golang-org-x-tools.changes 2018-02-06 16:49:11.687954256 +0100
+++ /work/SRC/openSUSE:Factory/.golang-org-x-tools.new/golang-org-x-tools.changes 2018-06-29 22:36:55.737974294 +0200
@@ -1,0 +2,6 @@
+Thu Jun 28 15:53:09 UTC 2018 - jmassaguerpla(a)suse.com
+
+- Require go >= 1.9 instead of go = 1.9 cause otherwise this package
+ does not build with go1.10 while its dependencies do
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ golang-org-x-tools.spec ++++++
--- /var/tmp/diff_new_pack.dyZCqv/_old 2018-06-29 22:36:56.393973725 +0200
+++ /var/tmp/diff_new_pack.dyZCqv/_new 2018-06-29 22:36:56.397973721 +0200
@@ -1,7 +1,7 @@
#
# spec file for package golang-org-x
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -35,13 +35,13 @@
Source2: godoc.service
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-BuildRequires: golang(API) = 1.9
BuildRequires: fdupes
BuildRequires: find
BuildRequires: golang-packaging
BuildRequires: mango-doc
BuildRequires: systemd
BuildRequires: xz
+BuildRequires: golang(API) >= 1.9
BuildRequires: golang-org-x-net-html
Requires: golang-org-x-net-html
@@ -140,7 +140,6 @@
%{_bindir}/tip
%{_bindir}/toolstash
-
%{_mandir}/man1/benchcmp.1*
%{_mandir}/man1/bundle.1*
%{_mandir}/man1/callgraph.1*
1
0
Hello community,
here is the log from the commit of package ntpsec for openSUSE:Factory checked in at 2018-06-29 22:36:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ntpsec (Old)
and /work/SRC/openSUSE:Factory/.ntpsec.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ntpsec"
Fri Jun 29 22:36:48 2018 rev:9 rq:619740 version:1.1.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/ntpsec/ntpsec.changes 2018-03-30 12:08:04.576316254 +0200
+++ /work/SRC/openSUSE:Factory/.ntpsec.new/ntpsec.changes 2018-06-29 22:36:51.125978298 +0200
@@ -1,0 +2,10 @@
+Fri Jun 29 08:57:44 UTC 2018 - tchvatal(a)suse.com
+
+- Update to 1.1.1:
+ * Log timestamps now include the year. This is useful when
+ investigating bugs involving time-setting and -g.
+ * Many internal cleanups to clear the way for upcoming major features.
+ They should generally not be user visible. Refer to the git-log if
+ you are interested.
+
+-------------------------------------------------------------------
Old:
----
ntpsec-1.1.0.tar.gz
ntpsec-1.1.0.tar.gz.asc
New:
----
ntpsec-1.1.1.tar.gz
ntpsec-1.1.1.tar.gz.asc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ntpsec.spec ++++++
--- /var/tmp/diff_new_pack.G5d20F/_old 2018-06-29 22:36:51.557977923 +0200
+++ /var/tmp/diff_new_pack.G5d20F/_new 2018-06-29 22:36:51.561977919 +0200
@@ -18,7 +18,7 @@
Name: ntpsec
-Version: 1.1.0
+Version: 1.1.1
Release: 0
Summary: Improved implementation of Network Time Protocol
License: BSD-2-Clause AND NTP AND BSD-3-Clause AND MIT
++++++ ntpsec-1.1.0.tar.gz -> ntpsec-1.1.1.tar.gz ++++++
++++ 9456 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package python-jwcrypto for openSUSE:Factory checked in at 2018-06-29 22:36:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jwcrypto (Old)
and /work/SRC/openSUSE:Factory/.python-jwcrypto.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jwcrypto"
Fri Jun 29 22:36:46 2018 rev:5 rq:619738 version:0.5.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-jwcrypto/python-jwcrypto.changes 2018-06-27 10:21:38.879541948 +0200
+++ /work/SRC/openSUSE:Factory/.python-jwcrypto.new/python-jwcrypto.changes 2018-06-29 22:36:46.857982002 +0200
@@ -1,0 +2,8 @@
+Wed Jun 27 20:45:14 UTC 2018 - michael(a)stroeder.com
+
+- update to upstream release 0.5.0:
+ * Better validation of JWE
+ * Avoid deprecation warnings
+ * Tested to work with python 3.7
+
+-------------------------------------------------------------------
Old:
----
jwcrypto-0.4.2.tar.gz
New:
----
jwcrypto-0.5.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-jwcrypto.spec ++++++
--- /var/tmp/diff_new_pack.NwN3rV/_old 2018-06-29 22:36:47.357981569 +0200
+++ /var/tmp/diff_new_pack.NwN3rV/_new 2018-06-29 22:36:47.361981565 +0200
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-jwcrypto
-Version: 0.4.2
+Version: 0.5.0
Release: 0
Summary: Python module package implementing JOSE Web standards
License: LGPL-3.0-only
++++++ jwcrypto-0.4.2.tar.gz -> jwcrypto-0.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/PKG-INFO new/jwcrypto-0.5.0/PKG-INFO
--- old/jwcrypto-0.4.2/PKG-INFO 2017-08-01 17:58:06.000000000 +0200
+++ new/jwcrypto-0.5.0/PKG-INFO 2018-06-27 12:27:24.000000000 +0200
@@ -1,10 +1,10 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: jwcrypto
-Version: 0.4.2
+Version: 0.5.0
Summary: Implementation of JOSE Web standards
Home-page: https://github.com/latchset/jwcrypto
-Author: JWCrypto Project Contributors
-Author-email: simo(a)redhat.com
+Maintainer: JWCrypto Project Contributors
+Maintainer-email: simo(a)redhat.com
License: LGPLv3+
Description: UNKNOWN
Platform: UNKNOWN
@@ -12,6 +12,7 @@
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/README.md new/jwcrypto-0.5.0/README.md
--- old/jwcrypto-0.4.2/README.md 2015-07-10 18:38:15.000000000 +0200
+++ new/jwcrypto-0.5.0/README.md 2018-06-27 08:24:18.000000000 +0200
@@ -1,3 +1,5 @@
+[](https:/…
+
JWCrypto
========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto/common.py new/jwcrypto-0.5.0/jwcrypto/common.py
--- old/jwcrypto-0.4.2/jwcrypto/common.py 2017-08-01 10:46:38.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto/common.py 2018-06-27 08:24:18.000000000 +0200
@@ -16,12 +16,12 @@
def base64url_decode(payload):
- l = len(payload) % 4
- if l == 2:
+ size = len(payload) % 4
+ if size == 2:
payload += '=='
- elif l == 3:
+ elif size == 3:
payload += '='
- elif l != 0:
+ elif size != 0:
raise ValueError('Invalid base64 string')
return urlsafe_b64decode(payload.encode('utf-8'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto/jwa.py new/jwcrypto-0.5.0/jwcrypto/jwa.py
--- old/jwcrypto-0.4.2/jwcrypto/jwa.py 2017-08-01 10:46:38.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto/jwa.py 2018-06-27 08:24:22.000000000 +0200
@@ -141,15 +141,15 @@
def sign(self, key, payload):
skey = key.get_op_key('sign', self._curve)
signature = skey.sign(payload, ec.ECDSA(self.hashfn))
- r, s = ec_utils.decode_rfc6979_signature(signature)
- l = key.get_curve(self._curve).key_size
- return _encode_int(r, l) + _encode_int(s, l)
+ r, s = ec_utils.decode_dss_signature(signature)
+ size = key.get_curve(self._curve).key_size
+ return _encode_int(r, size) + _encode_int(s, size)
def verify(self, key, payload, signature):
pkey = key.get_op_key('verify', self._curve)
r = signature[:len(signature) // 2]
s = signature[len(signature) // 2:]
- enc_signature = ec_utils.encode_rfc6979_signature(
+ enc_signature = ec_utils.encode_dss_signature(
int(hexlify(r), 16), int(hexlify(s), 16))
pkey.verify(enc_signature, payload, ec.ECDSA(self.hashfn))
@@ -828,7 +828,7 @@
class _EcdhEsAes256Kw(_EcdhEs):
name = 'ECDH-ES+A256KW'
- description = 'ECDH-ES using Concat KDF and "A128KW" wrapping'
+ description = 'ECDH-ES using Concat KDF and "A256KW" wrapping'
keysize = 256
algorithm_usage_location = 'alg'
algorithm_use = 'kex'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto/jwe.py new/jwcrypto-0.5.0/jwcrypto/jwe.py
--- old/jwcrypto-0.4.2/jwcrypto/jwe.py 2017-08-01 15:22:08.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto/jwe.py 2018-06-27 08:24:22.000000000 +0200
@@ -3,6 +3,7 @@
import zlib
from jwcrypto import common
+from jwcrypto.common import JWException
from jwcrypto.common import base64url_decode, base64url_encode
from jwcrypto.common import json_decode, json_encode
from jwcrypto.jwa import JWA
@@ -40,7 +41,7 @@
"""Default allowed algorithms"""
-class InvalidJWEData(Exception):
+class InvalidJWEData(JWException):
"""Invalid JWE Object.
This exception is raised when the JWE Object is invalid and/or
@@ -58,7 +59,7 @@
super(InvalidJWEData, self).__init__(msg)
-# These have been moved to jwcrypto.common, maintain here for bacwards compat
+# These have been moved to jwcrypto.common, maintain here for backwards compat
InvalidCEKeyLength = common.InvalidCEKeyLength
InvalidJWEKeyLength = common.InvalidJWEKeyLength
InvalidJWEKeyType = common.InvalidJWEKeyType
@@ -269,7 +270,19 @@
if compact:
for invalid in 'aad', 'unprotected':
if invalid in self.objects:
- raise InvalidJWEOperation("Can't use compact encoding")
+ raise InvalidJWEOperation(
+ "Can't use compact encoding when the '%s' parameter"
+ "is set" % invalid)
+ if 'protected' not in self.objects:
+ raise InvalidJWEOperation(
+ "Can't use compat encoding without protected headers")
+ else:
+ ph = json_decode(self.objects['protected'])
+ for required in 'alg', 'enc':
+ if required not in ph:
+ raise InvalidJWEOperation(
+ "Can't use compat encoding, '%s' must be in the "
+ "protected header" % required)
if 'recipients' in self.objects:
if len(self.objects['recipients']) != 1:
raise InvalidJWEOperation("Invalid number of recipients")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto/jwk.py new/jwcrypto-0.5.0/jwcrypto/jwk.py
--- old/jwcrypto-0.4.2/jwcrypto/jwk.py 2017-08-01 10:46:38.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto/jwk.py 2018-06-27 12:24:24.000000000 +0200
@@ -1,8 +1,9 @@
# Copyright (C) 2015 JWCrypto Project Contributors - see LICENSE file
import os
-
from binascii import hexlify, unhexlify
+from collections import namedtuple
+from enum import Enum
from cryptography import x509
from cryptography.hazmat.backends import default_backend
@@ -12,6 +13,7 @@
from six import iteritems
+from jwcrypto.common import JWException
from jwcrypto.common import base64url_decode, base64url_encode
from jwcrypto.common import json_decode, json_encode
@@ -22,36 +24,59 @@
'oct': 'Octet sequence'}
"""Registry of valid Key Types"""
+
# RFC 7518 - 7.5
# It is part of the JWK Parameters Registry, but we want a more
# specific map for internal usage
-JWKValuesRegistry = {'EC': {'crv': ('Curve', 'Public', 'Required'),
- 'x': ('X Coordinate', 'Public', 'Required'),
- 'y': ('Y Coordinate', 'Public', 'Required'),
- 'd': ('ECC Private Key', 'Private', None)},
- 'RSA': {'n': ('Modulus', 'Public', 'Required'),
- 'e': ('Exponent', 'Public', 'Required'),
- 'd': ('Private Exponent', 'Private', None),
- 'p': ('First Prime Factor', 'Private', None),
- 'q': ('Second Prime Factor', 'Private', None),
- 'dp': ('First Factor CRT Exponent', 'Private',
- None),
- 'dq': ('Second Factor CRT Exponent', 'Private',
- None),
- 'qi': ('First CRT Coefficient', 'Private', None)},
- 'oct': {'k': ('Key Value', 'Private', 'Required')}}
+class ParmType(Enum):
+ name = 'A string with a name'
+ b64 = 'Base64url Encoded'
+ b64U = 'Base64urlUint Encoded'
+ unsupported = 'Unsupported Parameter'
+
+
+JWKParameter = namedtuple('Parameter', 'description public required type')
+JWKValuesRegistry = {
+ 'EC': {
+ 'crv': JWKParameter('Curve', True, True, ParmType.name),
+ 'x': JWKParameter('X Coordinate', True, True, ParmType.b64),
+ 'y': JWKParameter('Y Coordinate', True, True, ParmType.b64),
+ 'd': JWKParameter('ECC Private Key', False, False, ParmType.b64),
+ },
+ 'RSA': {
+ 'n': JWKParameter('Modulus', True, True, ParmType.b64),
+ 'e': JWKParameter('Exponent', True, True, ParmType.b64U),
+ 'd': JWKParameter('Private Exponent', False, False, ParmType.b64U),
+ 'p': JWKParameter('First Prime Factor', False, False, ParmType.b64U),
+ 'q': JWKParameter('Second Prime Factor', False, False, ParmType.b64U),
+ 'dp': JWKParameter('First Factor CRT Exponent',
+ False, False, ParmType.b64U),
+ 'dq': JWKParameter('Second Factor CRT Exponent',
+ False, False, ParmType.b64U),
+ 'qi': JWKParameter('First CRT Coefficient',
+ False, False, ParmType.b64U),
+ 'oth': JWKParameter('Other Primes Info',
+ False, False, ParmType.unsupported),
+ },
+ 'oct': {
+ 'k': JWKParameter('Key Value', False, True, ParmType.b64),
+ }
+}
"""Registry of valid key values"""
-JWKParamsRegistry = {'kty': ('Key Type', 'Public', ),
- 'use': ('Public Key Use', 'Public'),
- 'key_ops': ('Key Operations', 'Public'),
- 'alg': ('Algorithm', 'Public'),
- 'kid': ('Key ID', 'Public'),
- 'x5u': ('X.509 URL', 'Public'),
- 'x5c': ('X.509 Certificate Chain', 'Public'),
- 'x5t': ('X.509 Certificate SHA-1 Thumbprint', 'Public'),
- 'x5t#S256': ('X.509 Certificate SHA-256 Thumbprint',
- 'Public')}
+JWKParamsRegistry = {
+ 'kty': JWKParameter('Key Type', True, None, None),
+ 'use': JWKParameter('Public Key Use', True, None, None),
+ 'key_ops': JWKParameter('Key Operations', True, None, None),
+ 'alg': JWKParameter('Algorithm', True, None, None),
+ 'kid': JWKParameter('Key ID', True, None, None),
+ 'x5u': JWKParameter('X.509 URL', True, None, None),
+ 'x5c': JWKParameter('X.509 Certificate Chain', True, None, None),
+ 'x5t': JWKParameter('X.509 Certificate SHA-1 Thumbprint',
+ True, None, None),
+ 'x5t#S256': JWKParameter('X.509 Certificate SHA-256 Thumbprint',
+ True, None, None)
+}
"""Regstry of valid key parameters"""
# RFC 7518 - 7.6
@@ -83,7 +108,7 @@
'secp521r1': 'P-521'}
-class InvalidJWKType(Exception):
+class InvalidJWKType(JWException):
"""Invalid JWK Type Exception.
This exception is raised when an invalid parameter type is used.
@@ -98,7 +123,7 @@
self.value, list(JWKTypesRegistry.keys()))
-class InvalidJWKUsage(Exception):
+class InvalidJWKUsage(JWException):
"""Invalid JWK usage Exception.
This exception is raised when an invalid key usage is requested,
@@ -123,7 +148,7 @@
valid)
-class InvalidJWKOperation(Exception):
+class InvalidJWKOperation(JWException):
"""Invalid JWK Operation Exception.
This exception is raised when an invalid key operation is requested,
@@ -150,7 +175,7 @@
valid)
-class InvalidJWKValue(Exception):
+class InvalidJWKValue(JWException):
"""Invalid JWK Value Exception.
This exception is raised when an invalid/unknown value is used in the
@@ -210,6 +235,7 @@
@classmethod
def generate(cls, **kwargs):
obj = cls()
+ kty = None
try:
kty = kwargs['kty']
gen = getattr(obj, '_generate_%s' % kty)
@@ -219,6 +245,7 @@
return obj
def generate_key(self, **params):
+ kty = None
try:
kty = params.pop('generate')
gen = getattr(self, '_generate_%s' % kty)
@@ -346,8 +373,26 @@
names.remove(name)
for name, val in iteritems(JWKValuesRegistry[kty]):
- if val[2] == 'Required' and name not in self._key:
+ if val.required and name not in self._key:
raise InvalidJWKValue('Missing required value %s' % name)
+ if val.type == ParmType.unsupported and name in self._key:
+ raise InvalidJWKValue('Unsupported parameter %s' % name)
+ if val.type == ParmType.b64 and name in self._key:
+ # Check that the value is base64url encoded
+ try:
+ base64url_decode(self._key[name])
+ except Exception: # pylint: disable=broad-except
+ raise InvalidJWKValue(
+ '"%s" is not base64url encoded' % name
+ )
+ if val[3] == ParmType.b64U and name in self._key:
+ # Check that the value is Base64urlUInt encoded
+ try:
+ self._decode_int(self._key[name])
+ except Exception: # pylint: disable=broad-except
+ raise InvalidJWKValue(
+ '"%s" is not Base64urlUInt encoded' % name
+ )
# Unknown key parameters are allowed
# Let's just store them out of the way
@@ -385,6 +430,19 @@
' "key_ops" values specified at'
' the same time')
+ @classmethod
+ def from_json(cls, key):
+ """Creates a RFC 7517 JWK from the standard JSON format.
+
+ :param key: The RFC 7517 representation of a JWK.
+ """
+ obj = cls()
+ try:
+ jkey = json_decode(key)
+ except Exception as e: # pylint: disable=broad-except
+ raise InvalidJWKValue(e)
+ return obj.import_key(**jkey)
+
def export(self, private_key=True):
"""Exports the key in the standard JSON format.
Exports the key regardless of type, if private_key is False
@@ -405,19 +463,23 @@
It fails if one is not available like when this function
is called on a symmetric key.
"""
+ pub = self._public_params()
+ return json_encode(pub)
+
+ def _public_params(self):
if not self.has_public:
raise InvalidJWKType("No public key available")
pub = {}
preg = JWKParamsRegistry
for name in preg:
- if preg[name][1] == 'Public':
+ if preg[name].public:
if name in self._params:
pub[name] = self._params[name]
reg = JWKValuesRegistry[self._params['kty']]
for param in reg:
- if reg[param][1] == 'Public':
+ if reg[param].public:
pub[param] = self._key[param]
- return json_encode(pub)
+ return pub
def _export_all(self):
d = dict()
@@ -439,6 +501,10 @@
return self._export_all()
raise InvalidJWKType("Not a symmetric key")
+ def public(self):
+ pub = self._public_params()
+ return JWK(**pub)
+
@property
def has_public(self):
"""Whether this JWK has an asymmetric Public key."""
@@ -446,7 +512,7 @@
return False
reg = JWKValuesRegistry[self._params['kty']]
for value in reg:
- if reg[value][1] == 'Public' and value in self._key:
+ if reg[value].public and value in self._key:
return True
@property
@@ -456,7 +522,7 @@
return False
reg = JWKValuesRegistry[self._params['kty']]
for value in reg:
- if reg[value][1] == 'Private' and value in self._key:
+ if not reg[value].public and value in self._key:
return True
return False
@@ -700,7 +766,7 @@
t = {'kty': self._params['kty']}
for name, val in iteritems(JWKValuesRegistry[t['kty']]):
- if val[2] == 'Required':
+ if val.required:
t[name] = self._key[name]
digest = hashes.Hash(hashalg, backend=default_backend())
digest.update(bytes(json_encode(t).encode('utf8')))
@@ -733,6 +799,12 @@
super(JWKSet, self).__setitem__('keys', _JWKkeys())
self.update(*args, **kwargs)
+ def __iter__(self):
+ return self['keys'].__iter__()
+
+ def __contains__(self, key):
+ return self['keys'].__contains__(key)
+
def __setitem__(self, key, val):
if key == 'keys':
self['keys'].add(val)
@@ -769,7 +841,7 @@
"""
try:
jwkset = json_decode(keyset)
- except:
+ except Exception: # pylint: disable=broad-except
raise InvalidJWKValue()
if 'keys' not in jwkset:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto/jws.py new/jwcrypto-0.5.0/jwcrypto/jws.py
--- old/jwcrypto-0.4.2/jwcrypto/jws.py 2017-08-01 10:46:38.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto/jws.py 2018-06-27 08:24:22.000000000 +0200
@@ -1,5 +1,6 @@
# Copyright (C) 2015 JWCrypto Project Contributors - see LICENSE file
+from jwcrypto.common import JWException
from jwcrypto.common import base64url_decode, base64url_encode
from jwcrypto.common import json_decode, json_encode
from jwcrypto.jwa import JWA
@@ -30,7 +31,7 @@
"""Default allowed algorithms"""
-class InvalidJWSSignature(Exception):
+class InvalidJWSSignature(JWException):
"""Invalid JWS Signature.
This exception is raised when a signature cannot be validated.
@@ -47,7 +48,7 @@
super(InvalidJWSSignature, self).__init__(msg)
-class InvalidJWSObject(Exception):
+class InvalidJWSObject(JWException):
"""Invalid JWS Object.
This exception is raised when the JWS Object is invalid and/or
@@ -63,7 +64,7 @@
super(InvalidJWSObject, self).__init__(msg)
-class InvalidJWSOperation(Exception):
+class InvalidJWSOperation(JWException):
"""Invalid JWS Object.
This exception is raised when a requested operation cannot
@@ -495,7 +496,7 @@
jhl = list()
for o in obj['signatures']:
jh = dict()
- if 'protected' in obj:
+ if 'protected' in o:
p = json_decode(o['protected'])
jh = self._merge_headers(jh, p)
jh = self._merge_headers(jh, o.get('header', dict()))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto/jwt.py new/jwcrypto-0.5.0/jwcrypto/jwt.py
--- old/jwcrypto-0.4.2/jwcrypto/jwt.py 2017-08-01 10:46:38.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto/jwt.py 2018-06-27 08:24:22.000000000 +0200
@@ -5,7 +5,7 @@
from six import string_types
-from jwcrypto.common import json_decode, json_encode
+from jwcrypto.common import JWException, json_decode, json_encode
from jwcrypto.jwe import JWE
from jwcrypto.jwk import JWK, JWKSet
from jwcrypto.jws import JWS
@@ -22,7 +22,7 @@
'jti': 'JWT ID'}
-class JWTExpired(Exception):
+class JWTExpired(JWException):
"""Json Web Token is expired.
This exception is raised when a token is expired accoring to its claims.
@@ -39,7 +39,7 @@
super(JWTExpired, self).__init__(msg)
-class JWTNotYetValid(Exception):
+class JWTNotYetValid(JWException):
"""Json Web Token is not yet valid.
This exception is raised when a token is not valid yet according to its
@@ -57,7 +57,7 @@
super(JWTNotYetValid, self).__init__(msg)
-class JWTMissingClaim(Exception):
+class JWTMissingClaim(JWException):
"""Json Web Token claim is invalid.
This exception is raised when a claim does not match the expected value.
@@ -74,7 +74,7 @@
super(JWTMissingClaim, self).__init__(msg)
-class JWTInvalidClaimValue(Exception):
+class JWTInvalidClaimValue(JWException):
"""Json Web Token claim is invalid.
This exception is raised when a claim does not match the expected value.
@@ -91,7 +91,7 @@
super(JWTInvalidClaimValue, self).__init__(msg)
-class JWTInvalidClaimFormat(Exception):
+class JWTInvalidClaimFormat(JWException):
"""Json Web Token claim format is invalid.
This exception is raised when a claim is not in a valid format.
@@ -108,7 +108,7 @@
super(JWTInvalidClaimFormat, self).__init__(msg)
-class JWTMissingKeyID(Exception):
+class JWTMissingKeyID(JWException):
"""Json Web Token is missing key id.
This exception is raised when trying to decode a JWT with a key set
@@ -126,7 +126,7 @@
super(JWTMissingKeyID, self).__init__(msg)
-class JWTMissingKey(Exception):
+class JWTMissingKey(JWException):
"""Json Web Token is using a key not in the key set.
This exception is raised if the key that was used is not available
@@ -155,15 +155,15 @@
"""Creates a JWT object.
:param header: A dict or a JSON string with the JWT Header data.
- :param claims: A dict or a string withthe JWT Claims data.
+ :param claims: A dict or a string with the JWT Claims data.
:param jwt: a 'raw' JWT token
:param key: A (:class:`jwcrypto.jwk.JWK`) key to deserialize
- the token. A (:class:`jwcrypt.jwk.JWKSet`) can also be used.
+ the token. A (:class:`jwcrypto.jwk.JWKSet`) can also be used.
:param algs: An optional list of allowed algorithms
:param default_claims: An optional dict with default values for
registred claims. A None value for NumericDate type claims
will cause generation according to system time. Only the values
- fro RFC 7519 - 4.1 are evaluated.
+ from RFC 7519 - 4.1 are evaluated.
:param check_claims: An optional dict of claims that must be
present in the token, if the value is not None the claim must
match exactly.
@@ -224,6 +224,10 @@
@claims.setter
def claims(self, c):
+ if self._reg_claims and not isinstance(c, dict):
+ # decode c so we can set default claims
+ c = json_decode(c)
+
if isinstance(c, dict):
self._add_default_claims(c)
self._claims = json_encode(c)
@@ -380,8 +384,8 @@
if value in claims[name]:
continue
raise JWTInvalidClaimValue(
- "Invalid '%s' value. Expected '%s' in '%s'" % (
- name, value, claims[name]))
+ "Invalid '%s' value. Expected '%s' to be in '%s'" % (
+ name, claims[name], value))
elif name == 'exp':
if value is not None:
@@ -398,7 +402,7 @@
else:
if value is not None and value != claims[name]:
raise JWTInvalidClaimValue(
- "Invalid '%s' value. Expected '%d' got '%d'" % (
+ "Invalid '%s' value. Expected '%s' got '%s'" % (
name, value, claims[name]))
def make_signed_token(self, key):
@@ -437,7 +441,7 @@
:param jwt: a 'raw' JWT token.
:param key: A (:class:`jwcrypto.jwk.JWK`) verification or
- decryption key, or a (:class:`jwcrypt.jwk.JWKSet`) that
+ decryption key, or a (:class:`jwcrypto.jwk.JWKSet`) that
contains a key indexed by the 'kid' header.
"""
c = jwt.count('.')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto/tests.py new/jwcrypto-0.5.0/jwcrypto/tests.py
--- old/jwcrypto-0.4.2/jwcrypto/tests.py 2017-08-01 10:46:38.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto/tests.py 2018-06-27 08:24:22.000000000 +0200
@@ -3,7 +3,6 @@
from __future__ import unicode_literals
import copy
-
import unittest
from cryptography.hazmat.backends import default_backend
@@ -329,6 +328,15 @@
ks3 = jwk.JWKSet.from_json(ks.export())
self.assertEqual(len(ks), len(ks3))
+ # Test Keyset with mutiple keys
+ ksm = jwk.JWKSet.from_json(json_encode(PrivateKeys))
+ num = 0
+ for item in ksm:
+ self.assertTrue(isinstance(item, jwk.JWK))
+ self.assertTrue(item in ksm)
+ num += 1
+ self.assertEqual(num, len(PrivateKeys['keys']))
+
def test_thumbprint(self):
for i in range(0, len(PublicKeys['keys'])):
k = jwk.JWK(**PublicKeys['keys'][i])
@@ -378,6 +386,25 @@
self.assertFalse(pubkey.has_private)
self.assertEqual(prikey.key_id, pubkey.key_id)
+ def test_public(self):
+ key = jwk.JWK.from_pem(RSAPrivatePEM, password=RSAPrivatePassword)
+ self.assertTrue(key.has_public)
+ self.assertTrue(key.has_private)
+ pubkey = key.public()
+ self.assertTrue(pubkey.has_public)
+ self.assertFalse(pubkey.has_private)
+ # finally check public works
+ e = jwe.JWE('plaintext', '{"alg":"RSA-OAEP","enc":"A256GCM"}')
+ e.add_recipient(pubkey)
+ enc = e.serialize()
+ d = jwe.JWE()
+ d.deserialize(enc, key)
+ self.assertEqual(d.payload, b'plaintext')
+
+ def test_invalid_value(self):
+ with self.assertRaises(jwk.InvalidJWKValue):
+ jwk.JWK(kty='oct', k=b'\x01')
+
# RFC 7515 - A.1
A1_protected = \
@@ -556,7 +583,11 @@
'key2': jwk.JWK(**A3_key),
'protected2': bytes(bytearray(A3_protected)).decode('utf-8'),
'header2': json_encode({"kid": "e9bc097a-ce51-4036-9562-d2ade882db0d"}),
- 'serialized': A6_serialized}
+ 'serialized': A6_serialized,
+ 'jose_header': [{"kid": "2010-12-29",
+ "alg": "RS256"},
+ {"kid": "e9bc097a-ce51-4036-9562-d2ade882db0d",
+ "alg": "ES256"}]}
A7_example = \
'{' + \
@@ -630,6 +661,7 @@
sig = s.serialize()
s.deserialize(sig, A6_example['key1'])
s.deserialize(A6_serialized, A6_example['key2'])
+ self.assertEqual(A6_example['jose_header'], s.jose_header)
def test_A7(self):
s = jws.JWS(A6_example['payload'])
@@ -843,6 +875,26 @@
e = jwe.JWE(algs=['A256KW'])
e.deserialize(E_A5_ex, E_A4_ex['key2'])
+ def test_compact_protected_header(self):
+ """Compact representation requires a protected header"""
+ e = jwe.JWE(E_A1_ex['plaintext'])
+ e.add_recipient(E_A1_ex['key'], E_A1_ex['protected'])
+
+ with self.assertRaises(jwe.InvalidJWEOperation):
+ e.serialize(compact=True)
+
+ def test_compact_invalid_header(self):
+ with self.assertRaises(jwe.InvalidJWEOperation):
+ e = jwe.JWE(E_A1_ex['plaintext'], E_A1_ex['protected'],
+ aad='XYZ', recipient=E_A1_ex['key'])
+ e.serialize(compact=True)
+
+ with self.assertRaises(jwe.InvalidJWEOperation):
+ e = jwe.JWE(E_A1_ex['plaintext'], E_A1_ex['protected'],
+ unprotected='{"jku":"https://example.com/keys.jwks"}',
+ recipient=E_A1_ex['key'])
+ e.serialize(compact=True)
+
MMA_vector_key = jwk.JWK(**E_A2_key)
MMA_vector_ok_cek = \
@@ -1018,6 +1070,39 @@
keyset.add(key)
jwt.JWT(jwt=token, key=keyset, check_claims={'exp': 1300819380})
+ def test_invalid_claim_type(self):
+ key = jwk.JWK(**E_A2_key)
+ claims = {"testclaim": "test"}
+ claims.update(A1_claims)
+ t = jwt.JWT(A1_header, claims)
+ t.make_encrypted_token(key)
+ token = t.serialize()
+
+ # Wrong string
+ self.assertRaises(jwt.JWTInvalidClaimValue, jwt.JWT, jwt=token,
+ key=key, check_claims={"testclaim": "ijgi"})
+
+ # Wrong type
+ self.assertRaises(jwt.JWTInvalidClaimValue, jwt.JWT, jwt=token,
+ key=key, check_claims={"testclaim": 123})
+
+ # Correct
+ jwt.JWT(jwt=token, key=key, check_claims={"testclaim": "test"})
+
+ def test_claim_params(self):
+ key = jwk.JWK(**E_A2_key)
+ default_claims = {"iss": "test", "exp": None}
+ string_claims = '{"string_claim":"test"}'
+ string_header = '{"alg":"RSA1_5","enc":"A128CBC-HS256"}'
+ t = jwt.JWT(string_header, string_claims,
+ default_claims=default_claims)
+ t.make_encrypted_token(key)
+ token = t.serialize()
+
+ # Check default_claims
+ jwt.JWT(jwt=token, key=key, check_claims={"iss": "test", "exp": None,
+ "string_claim": "test"})
+
class ConformanceTests(unittest.TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/jwcrypto.egg-info/PKG-INFO new/jwcrypto-0.5.0/jwcrypto.egg-info/PKG-INFO
--- old/jwcrypto-0.4.2/jwcrypto.egg-info/PKG-INFO 2017-08-01 17:58:06.000000000 +0200
+++ new/jwcrypto-0.5.0/jwcrypto.egg-info/PKG-INFO 2018-06-27 12:27:24.000000000 +0200
@@ -1,10 +1,10 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: jwcrypto
-Version: 0.4.2
+Version: 0.5.0
Summary: Implementation of JOSE Web standards
Home-page: https://github.com/latchset/jwcrypto
-Author: JWCrypto Project Contributors
-Author-email: simo(a)redhat.com
+Maintainer: JWCrypto Project Contributors
+Maintainer-email: simo(a)redhat.com
License: LGPLv3+
Description: UNKNOWN
Platform: UNKNOWN
@@ -12,6 +12,7 @@
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/setup.py new/jwcrypto-0.5.0/setup.py
--- old/jwcrypto-0.4.2/setup.py 2017-08-01 17:57:50.000000000 +0200
+++ new/jwcrypto-0.5.0/setup.py 2018-06-27 12:27:18.000000000 +0200
@@ -6,7 +6,7 @@
setup(
name = 'jwcrypto',
- version = '0.4.2',
+ version = '0.5.0',
license = 'LGPLv3+',
maintainer = 'JWCrypto Project Contributors',
maintainer_email = 'simo(a)redhat.com',
@@ -18,6 +18,7 @@
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
'Intended Audience :: Developers',
'Topic :: Security',
'Topic :: Software Development :: Libraries :: Python Modules'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jwcrypto-0.4.2/tox.ini new/jwcrypto-0.5.0/tox.ini
--- old/jwcrypto-0.4.2/tox.ini 2017-08-01 17:50:59.000000000 +0200
+++ new/jwcrypto-0.5.0/tox.ini 2018-06-27 12:24:24.000000000 +0200
@@ -1,5 +1,5 @@
[tox]
-envlist = lint,py27,py34,py35,py36,pep8py2,pep8py3,doc,sphinx
+envlist = lint,py27,py34,py35,py36,py37,pep8py2,pep8py3,doc,sphinx
skip_missing_interpreters = true
[testenv]
1
0
Hello community,
here is the log from the commit of package python-weave for openSUSE:Factory checked in at 2018-06-29 22:36:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-weave (Old)
and /work/SRC/openSUSE:Factory/.python-weave.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-weave"
Fri Jun 29 22:36:34 2018 rev:4 rq:619737 version:0.16.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-weave/python-weave.changes 2017-05-17 10:55:27.133558960 +0200
+++ /work/SRC/openSUSE:Factory/.python-weave.new/python-weave.changes 2018-06-29 22:36:46.309982478 +0200
@@ -1,0 +2,10 @@
+Wed Jun 27 22:25:21 UTC 2018 - mcepl(a)suse.com
+
+- Clean up SPEC, make tests running (py2k only, because of upstream)
+
+-------------------------------------------------------------------
+Thu Aug 24 13:57:16 UTC 2017 - jmatejek(a)suse.com
+
+- singlespec auto-conversion
+
+-------------------------------------------------------------------
@@ -11,0 +22 @@
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-weave.spec ++++++
--- /var/tmp/diff_new_pack.P3qT43/_old 2018-06-29 22:36:46.693982145 +0200
+++ /var/tmp/diff_new_pack.P3qT43/_new 2018-06-29 22:36:46.697982141 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-weave
#
-# Copyright (c) 2017 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,24 +16,37 @@
#
+# Please submit bugfixes or comments via http://bugs.opensuse.org/
+%define skip_python3 1
+%define oldpython python
+
+%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-weave
Version: 0.16.0
Release: 0
Summary: Weave: a C++ compiler for Python
License: BSD-3-Clause
Group: Development/Libraries/Python
-Url: http://www.github.com/scipy/weave
-Source: https://files.pythonhosted.org/packages/source/w/weave/weave-%{version}.tar…
-BuildRequires: python-devel
-BuildRequires: python-numpy-devel
-BuildRequires: python-scipy
+URL: http://www.github.com/scipy/weave
+Source0: https://files.pythonhosted.org/packages/source/w/weave/weave-%{version}.tar…
+BuildRequires: %{python_module devel}
+BuildRequires: %{python_module nose}
+BuildRequires: %{python_module numpy-devel}
+BuildRequires: %{python_module scipy}
+BuildRequires: fdupes
+BuildRequires: gcc-c++
+BuildRequires: python-rpm-macros
+# Required for the running of the testsuite
+BuildRequires: system-user-nobody
Requires: python-numpy
Requires: python-scipy
-Provides: python-scipy-weave = %{version}
-Obsoletes: python-scipy-weave < %{version}
Provides: python-weave-devel = %{version}
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
+%ifpython2
+Provides: %{oldpython}-scipy-weave = %{version}
+Obsoletes: %{oldpython}-scipy-weave < %{version}
+%endif
+%python_subpackages
%description
Weave provides tools for including C/C++ code within Python code. Inlining
@@ -48,20 +61,25 @@
%prep
%setup -q -n weave-%{version}
+sed -i -e '1d' weave/setup.py
%build
-python setup.py build
+%python_build
%install
-python setup.py install --prefix=%{_prefix} --root=%{buildroot}
-# Don't ship tests
-find %{buildroot}%{python_sitelib}/weave -type d -name tests | xargs rm -rf
-# Don't ship weave examples, they're marked as documentation:
-find %{buildroot}%{python_sitelib}/weave -type d -name examples | xargs rm -rf
-
-%files
-%defattr(-,root,root,-)
-%doc LICENSE.txt
+%python_install
+%{python_expand # Don't ship tests
+ rm -rfv %{buildroot}%{$python_sitelib}/weave/tests
+ # Deduplicate files
+ %fdupes %{buildroot}%{$python_sitelib}
+}
+
+%check
+export PYTHONPATH=.
+%python_exec -c 'import weave; weave.test(verbose=2)'
+
+%files %{python_files}
+%license LICENSE.txt
%doc doc/tutorial*
%{python_sitelib}/weave-%{version}-py*.egg-info
%{python_sitelib}/weave
1
0