Hello community,
here is the log from the commit of package python-keyrings.alt for openSUSE:Factory checked in at 2017-01-25 23:32:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-keyrings.alt (Old)
and /work/SRC/openSUSE:Factory/.python-keyrings.alt.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-keyrings.alt"
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-keyrings.alt/python-keyrings.alt.changes 2016-07-21 07:55:19.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-keyrings.alt.new/python-keyrings.alt.changes 2017-01-25 23:32:31.327686517 +0100
@@ -1,0 +2,22 @@
+Mon Jan 23 21:09:11 UTC 2017 - dmueller@suse.com
+
+- fix source url
+
+-------------------------------------------------------------------
+Sat Jan 14 18:57:11 UTC 2017 - hpj@urpla.net
+
+- update to version 2.0
+ - #12: Drop kwallet support, now superseded by the dual kwallet support in
+ keyring. (from me ;)
+
+- update to version 1.3
+ - #9: Moved base file backend functionality from 'keyrings.alt.file' to
+ 'keyrings.alt.base_file'. This allows the 'Windows' module to no longer
+ trigger a circular import with the 'file' module.
+
+- update to version 1.2
+ - Updated project skeleton. Tests now run under tox. Tagged commits are
+ automatically released to PyPI.
+ - #6: Added license file.
+
+-------------------------------------------------------------------
Old:
----
keyrings.alt-1.1.1.tar.gz
New:
----
keyrings.alt-2.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-keyrings.alt.spec ++++++
--- /var/tmp/diff_new_pack.WVUYQI/_old 2017-01-25 23:32:31.731625643 +0100
+++ /var/tmp/diff_new_pack.WVUYQI/_new 2017-01-25 23:32:31.731625643 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-keyrings.alt
#
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2016 LISA GmbH, Bingen, Germany.
#
# All modifications and additions to the file contributed by third parties
@@ -17,36 +17,37 @@
#
-%if 0%{?suse_version} && 0%{?suse_version} <= 1110
-%{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
-%else
-BuildArch: noarch
-%endif
Name: python-keyrings.alt
-Version: 1.1.1
+Version: 2.0
Release: 0
Summary: Alternate keyring implementations
License: MIT
Group: Development/Languages/Python
Url: https://github.com/jaraco/keyrings.alt
-Source: https://pypi.python.org/packages/27/d0/9207bf58de11735fe2239deaecb9eae1084e2887077a700ac8aa27bd8159/keyrings.alt-%{version}.tar.gz
+Source: https://pypi.io/packages/source/k/keyrings.alt/keyrings.alt-%{version}.tar.gz
BuildRequires: python-devel
-BuildRequires: python-fs
-BuildRequires: python-gdata
-BuildRequires: python-keyczar
BuildRequires: python-keyring
-# Testing requirements
-BuildRequires: python-mock
BuildRequires: python-pycrypto
BuildRequires: python-pytest-runner
BuildRequires: python-setuptools
BuildRequires: python-setuptools_scm
-Requires: python-fs
-Requires: python-gdata
+Requires: python-pycrypto
+BuildRequires: python-keyczar
Requires: python-keyczar
+BuildRequires: python-gdata
+Requires: python-gdata
+BuildRequires: python-fs
+Requires: python-fs
+BuildRequires: python-keyring
Requires: python-keyring
-Requires: python-pycrypto
+# Testing requirements
+BuildRequires: python-mock
BuildRoot: %{_tmppath}/%{name}-%{version}-build
+%if 0%{?suse_version} && 0%{?suse_version} <= 1110
+%{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
+%else
+BuildArch: noarch
+%endif
%description
Alternate keyring backend implementations for use with the
++++++ keyrings.alt-1.1.1.tar.gz -> keyrings.alt-2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/.gitignore new/keyrings.alt-2.0/.gitignore
--- old/keyrings.alt-1.1.1/.gitignore 2016-01-23 15:09:27.000000000 +0100
+++ new/keyrings.alt-2.0/.gitignore 1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-dist/
-build/
-.eggs/
-*.pyc
-*.egg-info/
-.cache/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/.hgtags new/keyrings.alt-2.0/.hgtags
--- old/keyrings.alt-1.1.1/.hgtags 2016-03-01 20:24:53.000000000 +0100
+++ new/keyrings.alt-2.0/.hgtags 1970-01-01 01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-b3173ad03e2b87d50ab31eecc5e6e57e9963785d 1.0
-f9defd8cbdfabaeb1739fd02929f272ba7e4be73 1.0.1
-acdefb2c6c473bf6460004dbbe1f62280fcdeac8 1.1
-43b2bf00ab0477d3734932feb05ce6d533df255a 1.1.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/.travis.yml new/keyrings.alt-2.0/.travis.yml
--- old/keyrings.alt-1.1.1/.travis.yml 2016-01-14 11:58:15.000000000 +0100
+++ new/keyrings.alt-2.0/.travis.yml 2016-12-22 18:51:45.000000000 +0100
@@ -1,8 +1,23 @@
sudo: false
language: python
python:
- - 2.7
- - 3.5
+- 2.7
+- 3.5
+install:
+- pip install tox "setuptools>=28.2"
script:
- - pip install -U pytest
- - python setup.py test
+- tox
+branches:
+ except:
+ - skeleton
+deploy:
+ provider: pypi
+ server: https://upload.pypi.org/legacy/
+ on:
+ tags: true
+ all_branches: true
+ python: 3.5
+ user: jaraco
+ distributions: dists
+ password:
+ secure: iRtbY9yEN8qwJ7wiycL8N5NdZhRDENT5M8Bkpm7YSN5OiM41LRwFYnHDoQhYpz9L/UdfbovgEvv1XsQX/o8XRTn5efmhXRgS/FY3cA7Ry0GG41hmk2fnAgYuivA8EGoPveS9CnbU71ikL0HjRHv93+7Pz1kyMEYXRUpbMZ16K74o1J1MLOoCdQXXlKWfYjqAV/BglWwjIkwXVmNM2JwGV7U2hJ8zjsX1Bn7XqsZdC2KB6jK1frVjEHDfbv3NLQYIzQYqGw8GMWa+9EGVfFzqPnQmUC3E5GA93rC1SceBUb2RDBfCUpyFkyin3lQ05EvyVJoIaZO56gJ9Py1XzzSinSTjylgTxvFWx4uweowv5oM9OWnV+3SsZDw5+55fW5CYiMjdqjLso83gTkc8jbDHeK73Yh0sju2+QnOejnMzKRaBtCBubUkL+TPjEzoeUYSKLgW+iVHIKNKEKNME/WLzNtEhQwEFbLD5u/0bmHMBFPt40cXv3kSz6tz7NSjCHyJbtsBnyadYWRQTTRoSPnNIt0P716feUY/R5/Am5TIo2ZHKkGbRkuqFcJoJYhKau2M24WkRA4og8uBSyliShovHkrbahe1MpbJ/ZtmIU583FQjxIlGQQtNPN4QTSnQ1fUpvyhQY89GupbSxuek7jlmxmIm9SgAy6w9PUDZ5FKuJzm4=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/CHANGES.rst new/keyrings.alt-2.0/CHANGES.rst
--- old/keyrings.alt-1.1.1/CHANGES.rst 2016-03-01 20:24:42.000000000 +0100
+++ new/keyrings.alt-2.0/CHANGES.rst 2016-12-22 18:51:45.000000000 +0100
@@ -1,3 +1,24 @@
+2.0
+===
+
+#12: Drop kwallet support, now superseded by the dual kwallet
+support in keyring.
+
+1.3
+===
+
+#9: Moved base file backend functionality from 'keyrings.alt.file'
+to 'keyrings.alt.base_file'. This allows the 'Windows' module to
+no longer trigger a circular import with the 'file' module.
+
+1.2
+===
+
+Updated project skeleton. Tests now run under tox. Tagged
+commits are automatically released to PyPI.
+
+#6: Added license file.
+
1.1.1
=====
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/LICENSE new/keyrings.alt-2.0/LICENSE
--- old/keyrings.alt-1.1.1/LICENSE 1970-01-01 01:00:00.000000000 +0100
+++ new/keyrings.alt-2.0/LICENSE 2016-12-22 18:51:45.000000000 +0100
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015-2016 Jason R. Coombs
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/PKG-INFO new/keyrings.alt-2.0/PKG-INFO
--- old/keyrings.alt-1.1.1/PKG-INFO 2016-03-01 20:25:02.000000000 +0100
+++ new/keyrings.alt-2.0/PKG-INFO 2016-12-22 18:53:14.000000000 +0100
@@ -1,17 +1,34 @@
Metadata-Version: 1.1
Name: keyrings.alt
-Version: 1.1.1
+Version: 2.0
Summary: Alternate keyring implementations
Home-page: https://github.com/jaraco/keyrings.alt
Author: Jason R. Coombs
Author-email: jaraco@jaraco.com
License: UNKNOWN
-Description: keyrings.alt
- ============
+Description: .. image:: https://img.shields.io/pypi/v/keyrings.alt.svg
+ :target: https://pypi.org/project/keyrings.alt
+
+ .. image:: https://img.shields.io/pypi/pyversions/keyrings.alt.svg
+
+ .. image:: https://img.shields.io/pypi/dm/keyrings.alt.svg
+
+ .. image:: https://img.shields.io/travis/jaraco/keyrings.alt/master.svg
+ :target: http://travis-ci.org/jaraco/keyrings.alt
Alternate keyring backend implementations for use with the
`keyring package https://pypi.python.org/pypi/keyring`_.
+ Docs
+ ====
+
+ There's `no good mechanism for publishing documentation
+ https://github.com/pypa/python-packaging-user-guide/pull/266`_
+ easily. If there's a documentation link above, it's probably
+ stale because PyPI-based documentation is deprecated. This
+ project may have documentation published at ReadTheDocs, but
+ probably not. Good luck finding it.
+
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/README.rst new/keyrings.alt-2.0/README.rst
--- old/keyrings.alt-1.1.1/README.rst 2016-01-14 16:58:19.000000000 +0100
+++ new/keyrings.alt-2.0/README.rst 2016-12-22 18:51:45.000000000 +0100
@@ -1,5 +1,22 @@
-keyrings.alt
-============
+.. image:: https://img.shields.io/pypi/v/keyrings.alt.svg
+ :target: https://pypi.org/project/keyrings.alt
+
+.. image:: https://img.shields.io/pypi/pyversions/keyrings.alt.svg
+
+.. image:: https://img.shields.io/pypi/dm/keyrings.alt.svg
+
+.. image:: https://img.shields.io/travis/jaraco/keyrings.alt/master.svg
+ :target: http://travis-ci.org/jaraco/keyrings.alt
Alternate keyring backend implementations for use with the
`keyring package https://pypi.python.org/pypi/keyring`_.
+
+Docs
+====
+
+There's `no good mechanism for publishing documentation
+https://github.com/pypa/python-packaging-user-guide/pull/266`_
+easily. If there's a documentation link above, it's probably
+stale because PyPI-based documentation is deprecated. This
+project may have documentation published at ReadTheDocs, but
+probably not. Good luck finding it.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/docs/conf.py new/keyrings.alt-2.0/docs/conf.py
--- old/keyrings.alt-1.1.1/docs/conf.py 2016-01-14 16:58:26.000000000 +0100
+++ new/keyrings.alt-2.0/docs/conf.py 2016-12-22 18:51:45.000000000 +0100
@@ -1,10 +1,11 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-import setuptools_scm
+import pkg_resources
extensions = [
'sphinx.ext.autodoc',
+ 'rst.linker',
]
# General information about the project.
@@ -12,8 +13,27 @@
copyright = '2016 Jason R. Coombs'
# The short X.Y version.
-version = setuptools_scm.get_version(root='..', relative_to=__file__)
+version = pkg_resources.require(project)[0].version
# The full version, including alpha/beta/rc tags.
release = version
master_doc = 'index'
+
+link_files = {
+ '../CHANGES.rst': dict(
+ using=dict(
+ GH='https://github.com',
+ project=project,
+ ),
+ replace=[
+ dict(
+ pattern=r"(Issue )?#(?P<issue>\d+)",
+ url='{GH}/jaraco/{project}/issues/{issue}',
+ ),
+ dict(
+ pattern=r"^(?m)((?Pv?\d+(\.\d+){1,2}))\n[-=]+\n",
+ with_scm="{text}\n{rev[timestamp]:%d %b %Y}\n",
+ ),
+ ],
+ ),
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/docs/history.rst new/keyrings.alt-2.0/docs/history.rst
--- old/keyrings.alt-1.1.1/docs/history.rst 2016-01-14 11:58:15.000000000 +0100
+++ new/keyrings.alt-2.0/docs/history.rst 2016-12-22 18:51:45.000000000 +0100
@@ -5,4 +5,4 @@
History
*******
-.. include:: ../CHANGES.rst
+.. include:: ../CHANGES (links).rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/docs/index.rst new/keyrings.alt-2.0/docs/index.rst
--- old/keyrings.alt-1.1.1/docs/index.rst 2016-01-14 16:59:51.000000000 +0100
+++ new/keyrings.alt-2.0/docs/index.rst 2016-12-22 18:51:45.000000000 +0100
@@ -27,11 +27,6 @@
:undoc-members:
:show-inheritance:
-.. automodule:: keyrings.alt.kwallet
- :members:
- :undoc-members:
- :show-inheritance:
-
.. automodule:: keyrings.alt.multi
:members:
:undoc-members:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/docs/requirements.txt new/keyrings.alt-2.0/docs/requirements.txt
--- old/keyrings.alt-1.1.1/docs/requirements.txt 1970-01-01 01:00:00.000000000 +0100
+++ new/keyrings.alt-2.0/docs/requirements.txt 2016-12-22 18:51:45.000000000 +0100
@@ -0,0 +1 @@
+rst.linker
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/keyrings/alt/Windows.py new/keyrings.alt-2.0/keyrings/alt/Windows.py
--- old/keyrings.alt-1.1.1/keyrings/alt/Windows.py 2016-01-14 12:15:59.000000000 +0100
+++ new/keyrings.alt-2.0/keyrings/alt/Windows.py 2016-12-22 18:51:45.000000000 +0100
@@ -6,7 +6,7 @@
from keyring.util import properties
from keyring.backend import KeyringBackend
from keyring.errors import PasswordDeleteError, ExceptionRaisedContext
-from . import file
+from . import file_base
try:
# prefer pywin32-ctypes
@@ -56,7 +56,7 @@
_win_crypto.__name__
return not bool(exc)
-class EncryptedKeyring(file.BaseKeyring):
+class EncryptedKeyring(file_base.Keyring):
"""
A File-based keyring secured by Windows Crypto API.
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/keyrings/alt/file.py new/keyrings.alt-2.0/keyrings/alt/file.py
--- old/keyrings.alt-1.1.1/keyrings/alt/file.py 2016-01-14 19:27:15.000000000 +0100
+++ new/keyrings.alt-2.0/keyrings/alt/file.py 2016-12-22 18:51:45.000000000 +0100
@@ -5,142 +5,16 @@
import base64
import sys
import json
-import abc
from keyring.py27compat import configparser
-from keyring.errors import PasswordDeleteError
-from keyring.backend import KeyringBackend
-from keyring.util import platform_, properties
+from keyring.util import properties
from keyring.util.escape import escape as escape_for_ini
+from . import file_base
-class FileBacked(object):
- @abc.abstractproperty
- def filename(self):
- """
- The filename used to store the passwords.
- """
-
- @properties.NonDataProperty
- def file_path(self):
- """
- The path to the file where passwords are stored. This property
- may be overridden by the subclass or at the instance level.
- """
- return os.path.join(platform_.data_root(), self.filename)
-
- def __repr__(self):
- tmpl = "<{self.__class__.__name__} at {self.file_path}>"
- return tmpl.format(**locals())
-
-
-class BaseKeyring(FileBacked, KeyringBackend):
- """
- BaseKeyring is a file-based implementation of keyring.
- This keyring stores the password directly in the file and provides methods
- which may be overridden by subclasses to support
- encryption and decryption. The encrypted payload is stored in base64
- format.
- """
-
- @abc.abstractmethod
- def encrypt(self, password):
- """
- Given a password (byte string), return an encrypted byte string.
- """
-
- @abc.abstractmethod
- def decrypt(self, password_encrypted):
- """
- Given a password encrypted by a previous call to `encrypt`, return
- the original byte string.
- """
-
- def get_password(self, service, username):
- """
- Read the password from the file.
- """
- service = escape_for_ini(service)
- username = escape_for_ini(username)
-
- # load the passwords from the file
- config = configparser.RawConfigParser()
- if os.path.exists(self.file_path):
- config.read(self.file_path)
-
- # fetch the password
- try:
- password_base64 = config.get(service, username).encode()
- # decode with base64
- password_encrypted = base64.decodestring(password_base64)
- # decrypted the password
- password = self.decrypt(password_encrypted).decode('utf-8')
- except (configparser.NoOptionError, configparser.NoSectionError):
- password = None
- return password
-
- def set_password(self, service, username, password):
- """Write the password in the file.
- """
- service = escape_for_ini(service)
- username = escape_for_ini(username)
-
- # encrypt the password
- password_encrypted = self.encrypt(password.encode('utf-8'))
- # encode with base64
- password_base64 = base64.encodestring(password_encrypted).decode()
-
- # ensure the file exists
- self._ensure_file_path()
-
- # load the keyring from the disk
- config = configparser.RawConfigParser()
- config.read(self.file_path)
-
- # update the keyring with the password
- if not config.has_section(service):
- config.add_section(service)
- config.set(service, username, password_base64)
-
- # save the keyring back to the file
- with open(self.file_path, 'w') as config_file:
- config.write(config_file)
-
- def _ensure_file_path(self):
- """
- Ensure the storage path exists.
- If it doesn't, create it with "go-rwx" permissions.
- """
- storage_root = os.path.dirname(self.file_path)
- if storage_root and not os.path.isdir(storage_root):
- os.makedirs(storage_root)
- if not os.path.isfile(self.file_path):
- # create the file without group/world permissions
- with open(self.file_path, 'w'):
- pass
- user_read_write = 0o600
- os.chmod(self.file_path, user_read_write)
-
- def delete_password(self, service, username):
- """Delete the password for the username of the service.
- """
- service = escape_for_ini(service)
- username = escape_for_ini(username)
- config = configparser.RawConfigParser()
- if os.path.exists(self.file_path):
- config.read(self.file_path)
- try:
- if not config.remove_option(service, username):
- raise PasswordDeleteError("Password not found")
- except configparser.NoSectionError:
- raise PasswordDeleteError("Password not found")
- # update the file
- with open(self.file_path, 'w') as config_file:
- config.write(config_file)
-
-class PlaintextKeyring(BaseKeyring):
+class PlaintextKeyring(file_base.Keyring):
"""Simple File Keyring with no encryption"""
priority = .5
@@ -158,6 +32,7 @@
"""
return password_encrypted
+
class Encrypted(object):
"""
PyCrypto-backed Encryption support
@@ -189,7 +64,7 @@
return password
-class EncryptedKeyring(Encrypted, BaseKeyring):
+class EncryptedKeyring(Encrypted, file_base.Keyring):
"""PyCrypto File Keyring"""
filename = 'crypted_pass.cfg'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/keyrings/alt/file_base.py new/keyrings.alt-2.0/keyrings/alt/file_base.py
--- old/keyrings.alt-1.1.1/keyrings/alt/file_base.py 1970-01-01 01:00:00.000000000 +0100
+++ new/keyrings.alt-2.0/keyrings/alt/file_base.py 2016-12-22 18:51:45.000000000 +0100
@@ -0,0 +1,138 @@
+from __future__ import with_statement
+
+import os
+import base64
+import abc
+
+from keyring.py27compat import configparser
+
+from keyring.errors import PasswordDeleteError
+from keyring.backend import KeyringBackend
+from keyring.util import platform_, properties
+from keyring.util.escape import escape as escape_for_ini
+
+
+class FileBacked(object):
+ @abc.abstractproperty
+ def filename(self):
+ """
+ The filename used to store the passwords.
+ """
+
+ @properties.NonDataProperty
+ def file_path(self):
+ """
+ The path to the file where passwords are stored. This property
+ may be overridden by the subclass or at the instance level.
+ """
+ return os.path.join(platform_.data_root(), self.filename)
+
+ def __repr__(self):
+ tmpl = "<{self.__class__.__name__} at {self.file_path}>"
+ return tmpl.format(**locals())
+
+
+class Keyring(FileBacked, KeyringBackend):
+ """
+ BaseKeyring is a file-based implementation of keyring.
+
+ This keyring stores the password directly in the file and provides methods
+ which may be overridden by subclasses to support
+ encryption and decryption. The encrypted payload is stored in base64
+ format.
+ """
+
+ @abc.abstractmethod
+ def encrypt(self, password):
+ """
+ Given a password (byte string), return an encrypted byte string.
+ """
+
+ @abc.abstractmethod
+ def decrypt(self, password_encrypted):
+ """
+ Given a password encrypted by a previous call to `encrypt`, return
+ the original byte string.
+ """
+
+ def get_password(self, service, username):
+ """
+ Read the password from the file.
+ """
+ service = escape_for_ini(service)
+ username = escape_for_ini(username)
+
+ # load the passwords from the file
+ config = configparser.RawConfigParser()
+ if os.path.exists(self.file_path):
+ config.read(self.file_path)
+
+ # fetch the password
+ try:
+ password_base64 = config.get(service, username).encode()
+ # decode with base64
+ password_encrypted = base64.decodestring(password_base64)
+ # decrypted the password
+ password = self.decrypt(password_encrypted).decode('utf-8')
+ except (configparser.NoOptionError, configparser.NoSectionError):
+ password = None
+ return password
+
+ def set_password(self, service, username, password):
+ """Write the password in the file.
+ """
+ service = escape_for_ini(service)
+ username = escape_for_ini(username)
+
+ # encrypt the password
+ password_encrypted = self.encrypt(password.encode('utf-8'))
+ # encode with base64
+ password_base64 = base64.encodestring(password_encrypted).decode()
+
+ # ensure the file exists
+ self._ensure_file_path()
+
+ # load the keyring from the disk
+ config = configparser.RawConfigParser()
+ config.read(self.file_path)
+
+ # update the keyring with the password
+ if not config.has_section(service):
+ config.add_section(service)
+ config.set(service, username, password_base64)
+
+ # save the keyring back to the file
+ with open(self.file_path, 'w') as config_file:
+ config.write(config_file)
+
+ def _ensure_file_path(self):
+ """
+ Ensure the storage path exists.
+ If it doesn't, create it with "go-rwx" permissions.
+ """
+ storage_root = os.path.dirname(self.file_path)
+ if storage_root and not os.path.isdir(storage_root):
+ os.makedirs(storage_root)
+ if not os.path.isfile(self.file_path):
+ # create the file without group/world permissions
+ with open(self.file_path, 'w'):
+ pass
+ user_read_write = 0o600
+ os.chmod(self.file_path, user_read_write)
+
+ def delete_password(self, service, username):
+ """Delete the password for the username of the service.
+ """
+ service = escape_for_ini(service)
+ username = escape_for_ini(username)
+ config = configparser.RawConfigParser()
+ if os.path.exists(self.file_path):
+ config.read(self.file_path)
+ try:
+ if not config.remove_option(service, username):
+ raise PasswordDeleteError("Password not found")
+ except configparser.NoSectionError:
+ raise PasswordDeleteError("Password not found")
+ # update the file
+ with open(self.file_path, 'w') as config_file:
+ config.write(config_file)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/keyrings/alt/kwallet.py new/keyrings.alt-2.0/keyrings/alt/kwallet.py
--- old/keyrings.alt-1.1.1/keyrings/alt/kwallet.py 2016-01-14 12:15:59.000000000 +0100
+++ new/keyrings.alt-2.0/keyrings/alt/kwallet.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,114 +0,0 @@
-from __future__ import absolute_import
-
-import os
-import sys
-
-from keyring.py27compat import unicode_str
-from keyring.backend import KeyringBackend
-from keyring.errors import PasswordDeleteError
-from keyring.errors import PasswordSetError, ExceptionRaisedContext
-from keyring.util import properties
-
-# mixing Qt4 & Qt5 causes errors and may segfault
-if 'PyQt5' not in sys.modules:
- try:
- from PyKDE4.kdeui import KWallet
- from PyQt4 import QtGui
- except ImportError:
- pass
-
-kwallet = None
-
-def open_kwallet(kwallet_module=None, qt_module=None):
-
- # If we specified the kwallet_module and/or qt_module, surely we won't need
- # the cached kwallet object...
- if kwallet_module is None and qt_module is None:
- global kwallet
- if not kwallet is None:
- return kwallet
-
- # Allow for the injection of module-like objects for testing purposes.
- if kwallet_module is None:
- kwallet_module = KWallet.Wallet
- if qt_module is None:
- qt_module = QtGui
-
- # KDE wants us to instantiate an application object.
- app = None
- if qt_module.qApp.instance() == None:
- app = qt_module.QApplication([])
- try:
- window = qt_module.QWidget()
- kwallet = kwallet_module.openWallet(
- kwallet_module.NetworkWallet(),
- window.winId(),
- kwallet_module.Synchronous)
- if kwallet is not None:
- if not kwallet.hasFolder('Python'):
- kwallet.createFolder('Python')
- kwallet.setFolder('Python')
- return kwallet
- finally:
- if app:
- app.exit()
-
-class QtKeyring(KeyringBackend):
- """KDE KWallet"""
-
- @properties.ClassProperty
- @classmethod
- def priority(cls):
- with ExceptionRaisedContext() as exc:
- KWallet.__name__
- if exc:
- raise RuntimeError("KDE libraries not available")
- if "DISPLAY" not in os.environ:
- raise RuntimeError("cannot connect to X server")
- # Infer if KDE environment is active based on environment vars.
- # TODO: Does PyKDE provide a better indicator?
- kde_session_keys = (
- 'KDE_SESSION_ID', # most environments
- 'KDE_FULL_SESSION', # openSUSE
- )
- if not set(os.environ).intersection(kde_session_keys):
- return 0
- return 5
-
- def get_password(self, service, username):
- """Get password of the username for the service
- """
- key = username + '@' + service
- network = KWallet.Wallet.NetworkWallet()
- wallet = open_kwallet()
- if wallet is None:
- # the user pressed "cancel" when prompted to unlock their keyring.
- return None
- if wallet.keyDoesNotExist(network, 'Python', key):
- return None
-
- result = wallet.readPassword(key)[1]
- # The string will be a PyQt4.QtCore.QString, so turn it into a unicode
- # object.
- return unicode_str(result)
-
- def set_password(self, service, username, password):
- """Set password for the username of the service
- """
- wallet = open_kwallet()
- if wallet is None:
- # the user pressed "cancel" when prompted to unlock their keyring.
- raise PasswordSetError("Cancelled by user")
- wallet.writePassword(username+'@'+service, password)
-
- def delete_password(self, service, username):
- """Delete the password for the username of the service.
- """
- key = username + '@' + service
- wallet = open_kwallet()
- if wallet is None:
- # the user pressed "cancel" when prompted to unlock their keyring.
- raise PasswordDeleteError("Cancelled by user")
- if wallet.keyDoesNotExist(wallet.walletName(), 'Python', key):
- raise PasswordDeleteError("Password not found")
- wallet.removeEntry(key)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/keyrings.alt.egg-info/PKG-INFO new/keyrings.alt-2.0/keyrings.alt.egg-info/PKG-INFO
--- old/keyrings.alt-1.1.1/keyrings.alt.egg-info/PKG-INFO 2016-03-01 20:25:02.000000000 +0100
+++ new/keyrings.alt-2.0/keyrings.alt.egg-info/PKG-INFO 2016-12-22 18:53:14.000000000 +0100
@@ -1,17 +1,34 @@
Metadata-Version: 1.1
Name: keyrings.alt
-Version: 1.1.1
+Version: 2.0
Summary: Alternate keyring implementations
Home-page: https://github.com/jaraco/keyrings.alt
Author: Jason R. Coombs
Author-email: jaraco@jaraco.com
License: UNKNOWN
-Description: keyrings.alt
- ============
+Description: .. image:: https://img.shields.io/pypi/v/keyrings.alt.svg
+ :target: https://pypi.org/project/keyrings.alt
+
+ .. image:: https://img.shields.io/pypi/pyversions/keyrings.alt.svg
+
+ .. image:: https://img.shields.io/pypi/dm/keyrings.alt.svg
+
+ .. image:: https://img.shields.io/travis/jaraco/keyrings.alt/master.svg
+ :target: http://travis-ci.org/jaraco/keyrings.alt
Alternate keyring backend implementations for use with the
`keyring package https://pypi.python.org/pypi/keyring`_.
+ Docs
+ ====
+
+ There's `no good mechanism for publishing documentation
+ https://github.com/pypa/python-packaging-user-guide/pull/266`_
+ easily. If there's a documentation link above, it's probably
+ stale because PyPI-based documentation is deprecated. This
+ project may have documentation published at ReadTheDocs, but
+ probably not. Good luck finding it.
+
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/keyrings.alt.egg-info/SOURCES.txt new/keyrings.alt-2.0/keyrings.alt.egg-info/SOURCES.txt
--- old/keyrings.alt-1.1.1/keyrings.alt.egg-info/SOURCES.txt 2016-03-01 20:25:02.000000000 +0100
+++ new/keyrings.alt-2.0/keyrings.alt.egg-info/SOURCES.txt 2016-12-22 18:53:14.000000000 +0100
@@ -1,15 +1,16 @@
-.gitignore
-.hgtags
.travis.yml
CHANGES.rst
+LICENSE
README.rst
conftest.py
pytest.ini
setup.cfg
setup.py
+tox.ini
docs/conf.py
docs/history.rst
docs/index.rst
+docs/requirements.txt
keyrings/__init__.py
keyrings.alt.egg-info/PKG-INFO
keyrings.alt.egg-info/SOURCES.txt
@@ -23,18 +24,18 @@
keyrings/alt/__init__.py
keyrings/alt/_win_crypto.py
keyrings/alt/file.py
+keyrings/alt/file_base.py
keyrings/alt/keyczar.py
-keyrings/alt/kwallet.py
keyrings/alt/multi.py
keyrings/alt/pyfs.py
tests/__init__.py
tests/mocks.py
+tests/requirements.txt
tests/test_Gnome.py
tests/test_Google.py
tests/test_Windows.py
tests/test_crypto.py
tests/test_file.py
tests/test_keyczar.py
-tests/test_kwallet.py
tests/test_multi.py
tests/test_pyfs.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/keyrings.alt.egg-info/entry_points.txt new/keyrings.alt-2.0/keyrings.alt.egg-info/entry_points.txt
--- old/keyrings.alt-1.1.1/keyrings.alt.egg-info/entry_points.txt 2016-03-01 20:25:02.000000000 +0100
+++ new/keyrings.alt-2.0/keyrings.alt.egg-info/entry_points.txt 2016-12-22 18:53:14.000000000 +0100
@@ -4,7 +4,6 @@
Windows (alt) = keyrings.alt.Windows
file = keyrings.alt.file
keyczar = keyrings.alt.keyczar
-kwallet = keyrings.alt.kwallet
multi = keyrings.alt.multi
pyfs = keyrings.alt.pyfs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/pytest.ini new/keyrings.alt-2.0/pytest.ini
--- old/keyrings.alt-1.1.1/pytest.ini 2016-01-14 11:58:15.000000000 +0100
+++ new/keyrings.alt-2.0/pytest.ini 2016-12-22 18:51:45.000000000 +0100
@@ -1,4 +1,4 @@
[pytest]
-norecursedirs=*.egg .eggs dist build
+norecursedirs=dist build .tox
addopts=--doctest-modules
doctest_optionflags=ALLOW_UNICODE ELLIPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/setup.cfg new/keyrings.alt-2.0/setup.cfg
--- old/keyrings.alt-1.1.1/setup.cfg 2016-03-01 20:25:02.000000000 +0100
+++ new/keyrings.alt-2.0/setup.cfg 2016-12-22 18:53:14.000000000 +0100
@@ -1,12 +1,15 @@
[aliases]
-release = sdist bdist_wheel build_sphinx upload upload_docs
-test = pytest
+release = dists upload
+dists = clean --all sdist bdist_wheel
[wheel]
universal = 1
+[upload]
+repository = https://upload.pypi.org/legacy/
+
[egg_info]
-tag_svn_revision = 0
tag_build =
tag_date = 0
+tag_svn_revision = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/setup.py new/keyrings.alt-2.0/setup.py
--- old/keyrings.alt-1.1.1/setup.py 2016-01-23 15:09:27.000000000 +0100
+++ new/keyrings.alt-2.0/setup.py 2016-12-22 18:51:45.000000000 +0100
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Generated by jaraco.develop 2.27.1
-# https://pypi.python.org/pypi/jaraco.develop
+
+# Project skeleton maintained at https://github.com/jaraco/skeleton
import io
import sys
@@ -10,51 +10,30 @@
with io.open('README.rst', encoding='utf-8') as readme:
long_description = readme.read()
-needs_pytest = {'pytest', 'test'}.intersection(sys.argv)
-pytest_runner = ['pytest_runner'] if needs_pytest else []
-needs_sphinx = {'release', 'build_sphinx', 'upload_docs'}.intersection(sys.argv)
-sphinx = ['sphinx'] if needs_sphinx else []
-needs_wheel = {'release', 'bdist_wheel'}.intersection(sys.argv)
+needs_wheel = {'release', 'bdist_wheel', 'dists'}.intersection(sys.argv)
wheel = ['wheel'] if needs_wheel else []
-test_requirements = [
- 'gdata',
- 'python-keyczar',
- 'fs>=0.5',
- 'pycrypto',
-]
-"dependencies for running tests"
-
-if sys.version_info >= (3, 0):
- # gdata doesn't currently install on Python 3. Omit it also.
- # http://code.google.com/p/gdata-python-client/issues/detail?id=229
- test_requirements.remove('gdata')
-
- # keyczar doesn't currently install on Python 3. Omit it also.
- # http://code.google.com/p/keyczar/issues/detail?id=125
- test_requirements.remove('python-keyczar')
+name = 'keyrings.alt'
+description = 'Alternate keyring implementations'
setup_params = dict(
- name='keyrings.alt',
+ name=name,
use_scm_version=True,
author="Jason R. Coombs",
author_email="jaraco@jaraco.com",
- description="Alternate keyring implementations",
+ description=description or name,
long_description=long_description,
- url="https://github.com/jaraco/keyrings.alt",
+ url="https://github.com/jaraco/" + name,
packages=setuptools.find_packages(exclude=['tests']),
include_package_data=True,
- namespace_packages=['keyrings'],
+ namespace_packages=name.split('.')[:-1],
install_requires=[
],
extras_require={
},
setup_requires=[
- 'setuptools_scm>=1.9',
- ] + pytest_runner + sphinx + wheel,
- tests_require=[
- 'keyring[test]',
- ] + test_requirements,
+ 'setuptools_scm>=1.15.0',
+ ] + wheel,
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
@@ -68,7 +47,6 @@
'Gnome = keyrings.alt.Gnome',
'Google = keyrings.alt.Google',
'keyczar = keyrings.alt.keyczar',
- 'kwallet = keyrings.alt.kwallet',
'multi = keyrings.alt.multi',
'pyfs = keyrings.alt.pyfs',
'Windows (alt) = keyrings.alt.Windows',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/tests/requirements.txt new/keyrings.alt-2.0/tests/requirements.txt
--- old/keyrings.alt-1.1.1/tests/requirements.txt 1970-01-01 01:00:00.000000000 +0100
+++ new/keyrings.alt-2.0/tests/requirements.txt 2016-12-22 18:51:45.000000000 +0100
@@ -0,0 +1,15 @@
+pytest >= 2.8
+backports.unittest_mock
+keyring[test]
+
+fs>=0.5,<2
+pycrypto
+
+# gdata doesn't currently install on Python 3
+# http://code.google.com/p/gdata-python-client/issues/detail?id=229
+gdata; python_version=="2.7"
+
+
+# keyczar doesn't currently install on Python 3.
+# http://code.google.com/p/keyczar/issues/detail?id=125
+python-keyczar; python_version=="2.7"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/tests/test_crypto.py new/keyrings.alt-2.0/tests/test_crypto.py
--- old/keyrings.alt-1.1.1/tests/test_crypto.py 2016-01-14 12:35:21.000000000 +0100
+++ new/keyrings.alt-2.0/tests/test_crypto.py 2016-12-22 18:51:45.000000000 +0100
@@ -1,5 +1,5 @@
import unittest
-import mock
+from unittest import mock
from .test_file import FileKeyringTests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/tests/test_kwallet.py new/keyrings.alt-2.0/tests/test_kwallet.py
--- old/keyrings.alt-1.1.1/tests/test_kwallet.py 2016-01-14 12:27:14.000000000 +0100
+++ new/keyrings.alt-2.0/tests/test_kwallet.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,81 +0,0 @@
-import unittest
-
-from keyrings.alt import kwallet
-from keyring.tests.test_backend import BackendBasicTests
-
-def is_qt4_supported():
- try:
- __import__('PyQt4.QtGui')
- except ImportError:
- return False
- return True
-
-@unittest.skipUnless(kwallet.QtKeyring.viable, "Need KWallet")
-class KDEKWalletTestCase(BackendBasicTests, unittest.TestCase):
-
- def init_keyring(self):
- return kwallet.QtKeyring()
-
-
-class UnOpenableKWallet(object):
- """A module-like object used to test KDE wallet fall-back."""
-
- Synchronous = None
-
- def openWallet(self, *args):
- return None
-
- def NetworkWallet(self):
- return None
-
-
-class FauxQtGui(object):
- """A fake module-like object used in testing the open_kwallet function."""
-
- class qApp:
- @staticmethod
- def instance():
- pass
-
- class QApplication(object):
- def __init__(self, *args):
- pass
-
- def exit(self):
- pass
-
- class QWidget(object):
- def __init__(self, *args):
- pass
-
- def winId(self):
- pass
-
-class KDEWalletCanceledTestCase(unittest.TestCase):
-
- def test_user_canceled(self):
- # If the user cancels either the "enter your password to unlock the
- # keyring" dialog or clicks "deny" on the "can this application access
- # the wallet" dialog then openWallet() will return None. The
- # open_wallet() function should handle that eventuality by returning
- # None to signify that the KWallet backend is not available.
- self.assertEqual(
- kwallet.open_kwallet(UnOpenableKWallet(), FauxQtGui()),
- None)
-
-
-@unittest.skipUnless(kwallet.QtKeyring.viable and
- is_qt4_supported(),
- "Need KWallet and Qt4")
-class KDEKWalletInQApplication(unittest.TestCase):
- def test_QApplication(self):
- try:
- from PyKDE4.kdeui import KWallet
- from PyQt4.QtGui import QApplication
- except:
- return
-
- app = QApplication([])
- wallet = kwallet.open_kwallet()
- self.assertIsInstance(wallet, KWallet.Wallet)
- app.exit()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/keyrings.alt-1.1.1/tox.ini new/keyrings.alt-2.0/tox.ini
--- old/keyrings.alt-1.1.1/tox.ini 1970-01-01 01:00:00.000000000 +0100
+++ new/keyrings.alt-2.0/tox.ini 2016-12-22 18:51:45.000000000 +0100
@@ -0,0 +1,6 @@
+[testenv]
+deps =
+ -rtests/requirements.txt
+
+commands = py.test {posargs}
+usedevelop = True